构造函数 - 在简单的命名空间中 - Javascript

时间:2015-05-17 12:38:04

标签: javascript object namespaces prototype

想要在命名空间内定义函数构造函数。到目前为止我定义构造函数的方式是一个没有NS的简单构造函数,并结合了原型继承。

代码看起来像:

 function mySuperObject() {
    var self = this;
    self.p1 = "";
    self.p2 = "jkejie";
    // and others
    }
 mySuperObject.prototype.func1 = function(){...}
 // and others

介绍命名空间:

在阅读了很多文章后,我决定以一种非常简单的方式来定义命名空间,也许是最简单的。  基本上它只是定义一个指向对象 - 文字的变量,而内容是对象(上面的代码片段中的" mySuperObject")。构造函数如下:mySuperObjectInNS。

对象的代码:

var MYNAMESPACE = {

    //some variable outside the object
    file : "ConstructorInNamespace_obj.js: ",

    //Defining contructor function inside a namespace
    mySuperObjectInNS : function(propOne, propTwo){

        var self = this;
        self.objectName = "mySuperObject";
        self.propertyOne = propOne;
        self.propertyTwo = propTwo;

        self.doSomething = function(){
            console.log(file + " doSomething called - function of object");
        };

        ///many more functions and attributes
    }
}

MYNAMESPACE.mySuperObjectInNS.prototype.specialFunction = function(){
    console.log(file + " specialFunction called - prototypical inheritance defined in file of object, outside of namespace");
};

///many more functions and attributes

在另一个文件中,可以对对象进行实例化,如下所示:

...
var objOne = new MYNAMESPACE.mySuperObjectInNS("param11", "40");
//following line works just fine
objOne.doSomething();
 ....

问题:

  • 在我看来,这一切都是关于定义一个Object-Literal和 我将遇到麻烦,我试图定义最新的"私人" 该对象的属性。它是否正确?
  • mySuperObjectInNS仍然是构造函数吗? (对我而言 似乎它是别的东西,即使我可以从中实例化对象。
  • 这是一个非常糟糕的命名空间方式还是有点好吗?

1 个答案:

答案 0 :(得分:4)

  

在我看来,这一切都是关于定义一个Object-Literal而且我将遇到麻烦,我试图定义的最新内容" private"该对象的属性。这是对的吗?

"私有财产"与使用对象进行命名空间无关。事实上,最初在回答这个问题时,我将其视为"私人功能"因为相关。

有许多方法可以在JavaScript中执行私有属性和半私有属性,但它们与创建构造函数的方式及其为对象提供的方法有关,而不是如何公开构造函数。 "命名空间"对象是关于如何公开构造函数的。

创建"私人"的一种常见模式属性是定义需要在构造函数中 中访问它们的方法,并生成"属性"构造函数中的局部变量(因此它们根本就不是属性),如下所示:

function SuperObject() {
    var privateInformation;

    this.method = function() {
        // This can access `privateInformation`, which is completely
        // hidden from outside the constructor
    };
}

如果你在"命名空间中做到这一点并不重要"模式或单独。

另一方面,

私有功能会影响模式。我将在下面展示。

提供私有函数的一个相当常见的变体是使用函数来创建对象,这也为您提供了创建私有函数的机会:

var TheNamespace = function() {
    function privateFunction() {
    }

    function SuperObject() {
        var privateInformation;

        this.method = function() {
            // This can access `privateInformation`, which is completely
            // hidden from outside the constructor
        };
    }

    SuperObject.prototype.otherMethod = function() {
        // Can't access `privateInformation`, but has the advantage
        // that the function is shared between instances
    };

    return {
        SuperObject: SuperObject
    };
}();

// usage
var s = new TheNamespace.SuperObject();
  

mySuperObjectInNS仍然是构造函数吗? (对我来说,它似乎是别的东西,即使我可以从中实例化对象。

是。构造函数是期望您使用new的任何函数。

  

这是一个非常糟糕的命名空间方式还是有点好吗?

将对象用作伪命名空间是常见的做法。您可能还会考虑各种asynchronous module definition(AMD)技术,这些技术主要使"命名空间"对象在很大程度上是不必要的。

重新评论:

  

你定义了一个自调用函数....它返回一个对象?

它不是 self -invoking函数,它是 inline -invoked函数,但是是的,它是一个函数返回一个对象。

  

(如果是这样,我认为缺少了parantheses)

不,我们不需要任何不在那里的parens,因为你看到的其他地方外部parens的唯一原因是告诉解析器这个词{{1} }启动一个表达而不是声明;我们之所以不需要,因为我们已经在作业的右侧,所以遇到function时没有歧义。

  

由于您提出了这种方式,是否有更好的方法来定义ns?

"更好的"是一个主观的术语。它为您提供了一个范围,您可以在其中定义您要询问的私人功能。

  

虽然我经常也看到了这个选项:function这是怎么回事?

如果您有多个文件会将内容添加到"命名空间" (很常见),那么你经常会在每一个中看到这一点:

var = {} | someNSName;

它的作用是声明变量如果之前没有声明它,并为其分配一个空对象如果它还没有有一个。在加载的第一个文件中,会发生这种情况:

  1. 处理var TheNamespace = TheNamespace || {}; 并创建一个新变量var,其值为TheNamespace

  2. 处理了undefined分配:由于TheNameSpace = TheNameSpace || {}是假的,curiously-powerful || operator会产生新的undefined,会被分配到{}

  3. 当加载 next 文件时,会发生这种情况:

    1. TheNamespace.是无操作,因为该变量已存在。

    2. 处理了var分配:由于TheNameSpace = TheNameSpace || {}有一个非TheNamespace对象引用,它的真实性,以及奇怪的强大null }运算符导致对象||引用的引用。

    3. 也就是说,它根本没有效果。

      使用它以便您可以按任何顺序加载文件,或者单独加载一个文件。

      以下是一个例子:

      TheNamespace

      thingy.js

      var TheNamespace = TheNamespace || {}; TheNamespace.Nifty = function() { function privateFunction() { } function Nifty() { var privateInformation; this.method = function() { // Can access `privateInformation` here }; } Nifty.prototype.otherMethod = function() { // ... }; return Nifty; }();

      thingy.js

      该基本模式有批次变体,特别是如果一个文件可能会向var TheNamespace = TheNamespace || {}; TheNamespace.Thingy = function() { function privateFunction() { } function Thingy() { var privateInformation; this.method = function() { // Can access `privateInformation` here }; } Thingy.prototype.otherMethod = function() { // ... }; return Thingy; }(); 添加多个内容。这是一个支持这么简洁的方法:

      TheNamespace