繁体   English   中英

这是用于制作将各种方法封装到不同对象中的命名空间的正确javascript吗?

[英]Is this proper javascript for making a namespace that encapsulates various methods into different objects?

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,以便于维护

那我就可以...

 namespaced.Aj(); namespaced.Cd(); 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.Aj() ,则必须将A声明为对象,而不是函数:

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

        someProperty: 5,     

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

因此,这取决于最终要实现的目标...为了更好地了解这些方法,我建议使用JavaScript Patterns

这是您需要了解的关于JavaScript的内容:

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

您正在创建一个对象(并将其分配给obj ),该对象具有名为ABC属性,分别映射到值abc 这些值很可能是函数,因此当您拥有

    var obj = { A: function(){...} };

您正在创建一个具有称为“ A”的函数的属性的对象。 您可以使用obj.A进行引用,并使用obj.A()调用。

  • 当您调用obj.A() ,函数A体内的关键字this将引用obj 您可以使用它为obj分配新属性:
    var obj = {  
        A: function() { this.prop = "Hello!"; }
    };  
    obj.A();  
    alert( obj.prop ); // alerts "Hello!"

因此,在namespaced.Aj()内部, this关键字将指向namespace.A (这是最后一个点左侧的内容)。

  • 您可以将函数应用于对象,例如: func.apply(obj)或类似函数: func.call(obj) 在这种情况下, this关键字将改为引用obj 这与您的情况无关,但是如果func接受参数(例如param1param2 ),则可以像这样应用函数: func.apply(obj, [val1, val2])或类似地: func.call(obj, val1, val2)

  • 在函数内部声明的所有变量仅存在于该函数内部。 它们在外面不可见。 当您编写function doStuff(){}时(就像我在这里简化的那样)就像您编写var doStuff = function(){};一样好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! :)

所以你可以这样:

    function Duck(name){
        this.myName = name;
        this.quack = function(){
            alert(this.myName + " quacks!");
        }
    };
    donald = new Duck('Donald');
    donald.quack();


考虑到以上所有内容,编写命名空间代码的方法如下所示:

 // The following syntax, confusing to someone who hasn't seen it before, // is defining a new anonymous function and immediately using it // as a constructor applied to a new empty object. // // Alternatively, you can use this syntax: // var namespaced = {}; // (function(){ // .... // }).apply(namespaced); // var namespaced = new (function(){ // This creates a new variable named "namespaced" // which is visible only inside this anonymous function. // This variable points to the still-empty object created by // 'new'. This object will, once we're done with this anonymous function, // be assigned to a variable, outside, which by "coincidence" is // also named "namespaced". var namespaced = this; // You could alternatively not create the variable "namespaced" // and use 'this' directly inside this anonymous function. But, // the 'this' keyword may point to different objects inside the // nested functions that follow, so we create it to avoid confusion. // This assigns a new object to variable 'A', which isn't visible outside. // Use a constructor function defined inline. var A = new (function(){ var A = this; // 'this' now refers to the empty object created just above this.someProperty = 5; // Two different ways of A.anotherProperty = 7; // doing mostly the same thing this.j = function(){ //do some more stuff // 'this' will point to j, here return something; } // Function r isn't visible outside of A's constructor like this! function r(){ //do some stuff return something; } // Make 'r' visible outside by assigning it to a property of 'A'. // Look, it's also called "r". What fun! Ar = r; })(); // Make the object in variable 'A' visible outside of // 'namespaced's constructor, by making it a property of 'namespaced' namespaced.A = A; // Create a new object as before. // This time we won't make it visible outside // of "namespaced"'s constructor. var C = new (function(){ this.d = function (){ //do stuff we like } })(); // Give "namespaced" a property 'B'. // This time it's a function instead of a nested object. namespaced.B = function(){ // It's cool to make these function calls here, because // (a) nested functions can see the variables ('A' & 'C') // of surrounding functions, even if they terminate in the meantime; // and (b) 'r' & 'd' are properties of 'A' and 'C'. Ar(); Cd(); }; // You could return 'this' or 'namespaced' from this constructor, // but the 'new' keyword will make sure the "namespaced" variable // outside will get the no-longer-empty object it created, // so you can just not return anything. })(); // Now you can do five = namespaced.A.someProperty; seven = namespaced.A.anotherProperty; something = namespaced.Aj(); namespaced.B(); // Calls Ar() and Cd() // But you can't do namespaced.Cd(); // WRONG: "namespaced" doesn't have a property named "C" 

我希望这能带来更多帮助,而不是造成混淆。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM