这是用于创建将各种方法封装到不同对象中的名称空间的正确 JavaScript 吗?

发布于 2024-10-05 10:52:44 字数 768 浏览 2 评论 0原文

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

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
        }    
    }
}

Then I could do...

namespaced.A.j();

namespaced.C.d();

something = namespaced.A.someProperty;

right?

Would I need to do this too?

var something = new namespaced.A()?

If so does A() have a constructor? I'm really confused here :{

I'm trying to encapsulate my javascript so it's easy to maintain

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情愿 2024-10-12 10:52:44

那么我可以做...

namespaced.Aj();
命名空间.Cd();
某事=命名空间.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 模式

Then I could do...

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

No you couldn't. The function j and someProperty are only local to A and are not propagated to the outside. If you want to access them from the outside, you have to make them a property of the function, using 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;
        };
    }
}

But you would still need to call var a = new namespaced.A() in order to access the functions.

If you want to call namespaced.A.j() directly, you would have to declare A as object, not as function:

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

        someProperty: 5,     

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

So it depends on what you want to achieve eventually... to get a better insight into these methods, I recommend JavaScript Patterns.

只是我以为 2024-10-12 10:52:44

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

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

您正在创建(并分配给 obj)一个具有名为 AB 属性的对象> 和 C 分别映射到值 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(){}; 一样好,所以嵌套函数live 且只能在周围函数内部使用;也就是说,除非您将它们分配给可从外部访问的内容。

  • 当您调用诸如 new Cons() 之类的内容时,会创建一个新的空对象,然后在该对象上应用 Cons() 。换句话说,它与

     var obj = {};
    应用(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();


With all the preceding in mind, a way to write namespaced code is like this:

// 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!
        A.r = 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'.
        A.r();
        C.d();
    };


    // 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.A.j();

namespaced.B(); // Calls A.r() and C.d()

// But you can't do
namespaced.C.d(); // WRONG: "namespaced" doesn't have a property named "C"

我希望这能有所帮助,而不是造成困惑。

This is what you need to understand about JavaScript:

  • When you write
    var obj = { A: a, B: b, C: c };

you are creating (and assigning to obj) an object with properties called A, B and C mapping to values a, b and c respectively. These values may very well be functions, so when you have

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

you are creating an object with a property called "A" which is a function. You can refer to it with obj.A and call with obj.A().

  • When you call obj.A(), the keyword this inside the body of function A will refer to obj. You can use it to assign new properties to obj:
    var obj = {  
        A: function() { this.prop = "Hello!"; }
    };  
    obj.A();  
    alert( obj.prop ); // alerts "Hello!"

So, inside namespaced.A.j() the this keyword will point to namespace.A (it's what is to the left of the last dot).

  • You can apply a function to an object like so: func.apply(obj) or like so: func.call(obj). In this case, the this keyword will refer to obj instead. This isn't relevant to your case, but if func takes parameters (let's say param1 and param2), you can apply the function like so: func.apply(obj, [val1, val2]) or like so: func.call(obj, val1, val2).

  • All variables declared inside a function live only inside that function. They are not visible outside. And when you write function doStuff(){} it's (I'm simplifying here) as good as if you wrote var doStuff = function(){}; So nested functions live and can be used only inside the surrounding function; that is, unless you assign them to something accessible from outside.

  • When you call something like new Cons() what happens is the creation of a new empty object followed by the application of Cons() on that object. In other words, it's the same as

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

    or if you prefer:

    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! :)

So you can have this:

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


With all the preceding in mind, a way to write namespaced code is like this:

// 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!
        A.r = 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'.
        A.r();
        C.d();
    };


    // 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.A.j();

namespaced.B(); // Calls A.r() and C.d()

// But you can't do
namespaced.C.d(); // WRONG: "namespaced" doesn't have a property named "C"

I hope this helps more than it confuses.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文