簡體   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