JavaScript library pattern

JavaScript library pattern

本文关键字:pattern library JavaScript      更新时间:2023-09-26

我试图找出创建JavaScript库(类)的基本模式。我想这样做,它不会用一堆垃圾污染全局命名空间,但允许类具有实例变量和修改这些实例变量的公共方法。

考虑下面的玩具示例。我想创建一个类Foo。它应该包含一个实例成员bar,这是一个数字。Foo应该有一个构造函数,它接受一个数字,并用这个数字初始化它的实例bar。应该有一个实例方法,我可以调用Foo对象来修改bar。也许使用库的代码看起来像这样:

var foo1 = new Foo(1);
var foo2 = new Foo(2);
console.log(foo1.bar); // should print "1"
console.log(foo2.bar); // should print "2"
foo2.changeBar(42);
console.log(foo1.bar); // should print "1"
console.log(foo2.bar); // should print "42"

生成的foo.js将由Web应用程序使用,因此通过HTML中的脚本标记包含。

我已经用谷歌做了一些搜索,但我还没有找到一个单一的,简洁的,通用的大纲如何设计一个JavaScript类(用作库)。

(function () {
    Foo = function (num) {
         this.changeBar(num);
    };
    var privateMethod = function (x) {
        if (this.bar === 999) {
            this.bar = x;
        }
    };
    Foo.prototype.changeBar = function (num) {
        this.bar = num;
        privateMethod.call(this, 1);
    };
}());

那是做这件事最简单的方法。你不需要在闭包中包含定义,更多的是一个风格的东西。

以Evan的回答为基础,展示更多的可能性。大多数正常情况下只使用其中的一些。

(function() {
    //When we create variables inside a function they can only be seen by other
    // inner functions. Wraping all our code here makes sure noone gets to see
    // the private stuff.
    //The first opening parenthesis is required for Javascript to parse it
    //correctly though

    //this is the constructor function
    //Note how we set a global variable (Foo) to make it available outside.
    Foo = function(num, another_num) {
        this.changeBar(num);
        //sometimes you will want to make a method that modifies a variable
        //that can't be acessed via this.xxx. You can use a closure here for that
        //(there are some performance considerations though)
        this.baz = function(){
            console.log(another_num);
        }
        //Setting methods "by hand" like this is also useful if you want to
        //do multiple inheritance, since you can just set all methods of the
        //second class by hand here if you want.
    }
    //Things on Foo.prototype will be available for all Foo objects,
    // via prototypal inheritance magic.
    Foo.prototype.changeBar = function(num) {
        this.bar = num;
    }
    var a_secret_variable = 42;
    function my_private_function(){
        console.log(a_secret_variable);
    }
    //All private variables can be normaly used (by functions that can see them).
    Foo.prototype.use_magic = function(){
        my_private_function();
    }
}());
 //The "fake" function is imediatelly called,
 //so in the end all it does is create a inner scope.

模块模式可能是目前使用的最流行的模式。

var Foo = (function() {
    var _thisIsAPrivateVar;
    function thisIsAPrivateMethod() {
    }
    return {
        thisIsAPublicMethod : function() {
            // can still access the "private" variable and method
        }
    };
})();