这个正确的javascript用于创建一个命名空间,将各种方法封装到不同的对象中吗?

时间:2010-12-01 20:21:48

标签: javascript namespaces object encapsulation

var namespaced = {
    A: function(){
        function r(){
            //do some stuff
            return something;
        }

        var someProperty = 5;     

        function j(){
            //do some more stuff
            return something;
        }     
    },

    B: function(){   
        //can I call A and C?
        A.r();
        C.d();
    },

    C: function(){
        function d() {
            //do stuff we like
        }    
    }
}

然后我可以做......

namespaced.A.j();

namespaced.C.d();

something = namespaced.A.someProperty;

正确?

我也需要这样做吗?

var something = new namespaced.A()?

如果是这样,A()有一个构造函数?我真的很困惑:{

我正在尝试封装我的javascript,因此很容易维护

2 个答案:

答案 0 :(得分:4)

  

然后我可以做......

namespaced.A.j();
namespaced.C.d();
something = namespaced.A.someProperty;

不,你不能。函数jsomeProperty仅位于A的本地,不会传播到外部。如果你想从外面访问它们,你必须使用this使它们成为函数的属性:

var namespaced = {
    A: function(){
        this.r = function(){
            //do some stuff
            return something;
        };

        this.someProperty = 5;     

        this.j = function(){
            //do some more stuff
            return something;
        };
    }
}

但您仍需要致电var a = new namespaced.A()才能访问这些功能。

如果您想直接致电namespaced.A.j(),则必须将A声明为对象,而不是函数:

var namespaced = {
    A: {
        r: function(){
            //do some stuff
            return something;
        },

        someProperty: 5,     

        j: function(){
            //do some more stuff
            return something;
        }     
    }
}

所以这取决于你最终要达到的目标...为了更好地了解这些方法,我建议JavaScript Patterns

答案 1 :(得分:2)

这是您需要了解的JavaScript:

  • 写作时
    var obj = { A: a, B: b, C: c };

您正在创建一个对象,并将objAB属性映射到值C,{{1分别和a。这些值很可能是函数,所以当你有

b

您正在创建一个具有名为“A”的属性的对象,该属性是一个函数。您可以使用c引用该邮件并使用 var obj = { A: function(){...} }; 进行调用。

  • 当您致电obj.A时,函数obj.A()正文中的关键字obj.A()将引用this。您可以使用它为A分配新属性:
obj

因此,在obj内, var obj = { A: function() { this.prop = "Hello!"; } }; obj.A(); alert( obj.prop ); // alerts "Hello!" 关键字将指向namespaced.A.j()(它位于最后一个点的左侧)。

  • 您可以将函数应用于如下对象:this或类似:namespace.A。在这种情况下,func.apply(obj)关键字将引用func.call(obj)。这与您的情况无关,但如果this采用参数(例如objfunc),您可以应用如下函数:param1或类似:param2

  • 在函数内声明的所有变量仅在该函数内部存在。它们在外面不可见。当你写func.apply(obj, [val1, val2])时(我在这里简化)就像写func.call(obj, val1, val2)一样好。所以嵌套函数是实时的,只能在周围函数内部使用;也就是说,除非您将它们分配给可从外部访问的内容。

  • 当您调用function doStuff(){}之类的内容时,会发生一个新的空对象,然后在该对象上应用var doStuff = function(){};。换句话说,它是一样的

    new Cons()
    或者如果您愿意:

Cons()

所以你可以拥有这个:

    var obj = {};
Cons.apply(obj);

<小时/> 考虑到上述所有内容,编写命名空间代码的方法如下:

    var obj = {};
    obj.Cons = Cons;
    obj.Cons();
    // obj's Cons property then mysteriously disappears
    // unless it was explicitly set inside Cons() (oh my, how confusing! :)

我希望这有助于解决问题。