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

Constructor function - in simple namespace - Javascript

本文关键字:命名空间 Javascript 简单 构造函数      更新时间:2023-09-26

我们想在命名空间中定义一个函数构造函数。到目前为止,我定义构造函数的方式是一个没有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();
 ....

问题:

  • 在我看来,这一切都是关于定义对象文字和当我试图给"私人"下定义时,我会遇到麻烦的。对象的属性。这是正确的吗?
  • mySuperObjectInNS仍然是构造函数吗?(对我来说似乎是别的东西,即使我可以从它实例化对象。
  • 这是一种非常糟糕的命名空间方式还是还行?

在我看来,这一切都是关于定义一个object - literal,我将遇到麻烦,最近我试图定义该对象的"私有"属性。这是正确的吗?

"私有属性"与使用对象作为命名空间无关。事实上,最初在回答这个问题时,我将其理解为"私有函数",因为将与相关。

在JavaScript中有很多方法可以实现私有和半私有属性,但它们与如何创建构造函数和它提供给对象的方法有关,而不是如何暴露构造函数。"Namespace"对象是关于如何公开构造函数的。 创建"私有"属性的一个常见模式是在构造函数中定义需要访问它们的方法,并使"属性"在构造函数中成为局部变量(因此它们根本不是真正的属性),如下所示:
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的任何函数。

这是一种非常糟糕的命名空间方式还是还行?

使用对象作为伪名称空间是常见的做法。您还可以考虑各种异步模块定义(AMD)技术,这些技术在很大程度上使"名称空间"对象在很大程度上不必要。


你的评论:

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

它不是一个self调用函数,它是一个内联调用函数,但是,是的,它是一个返回对象的函数。

(如果是这样,我认为括号缺失)

不,我们不需要任何不在那里的父级,因为外部父级的唯一原因是告诉解析器单词function开始一个表达式而不是声明;在上面的代码中,我们不需要这样做,因为我们已经在赋值操作的右边了,所以当遇到function时不会有歧义。

由于你提出了这种方式,这是一个更好的方式来定义ns吗?

"更好"是一个主观术语。它给了你一个作用域,你可以在其中定义私有函数,这是你问过的。

然而我也经常看到选项:var = {} | someNSName;这是什么?

如果您有几个文件将向"命名空间"添加内容(这是常见的),那么您经常会在每个文件中看到以下内容:

var TheNamespace = TheNamespace || {};

的作用是,如果以前没有声明过变量,则声明该变量,如果还没有,则为其赋值一个空对象。在加载的第一个文件中,如下所示:

  1. var被处理并创建一个新的变量TheNamespace,其值为undefined

  2. 处理TheNameSpace = TheNameSpace || {}赋值:由于undefined是假的,功能强大的||运算符产生新的{},它被赋值给TheNamespace.

下一个文件加载时,发生以下情况:

  1. var是no-op,因为该变量已经存在。

  2. TheNameSpace = TheNameSpace || {}赋值被处理:由于TheNamespace有一个非null的对象引用,它是真实的,并且功能强大的||运算符导致对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。这里有一个非常简洁的例子:

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