构造函数 - 在简单命名空间中 - Javascript
Constructor function - in simple namespace - Javascript
想在命名空间内定义一个函数构造函数。到目前为止,我定义构造函数的方式是一个没有 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();
....
问题:
- 在我看来,这一切都是关于定义对象字面量和
我最近会遇到麻烦我正在尝试定义"private"
该对象的属性。这个对吗?
- 那个mySuperObjectInNS还是构造函数吗? (对我来说
似乎是别的东西,即使我可以从中实例化对象。
- 这是一种非常糟糕的命名空间方式还是还可以?
It seems to me that this all is about defining an Object-Literal and I will come into trouble the latest I am trying to define "private" properties of that object. Is this correct?
"Private properties" 与使用对象进行命名空间无关。事实上,最初在回答这个问题时,我读作 "private functions" 因为 会 是相关的。
在JavaScript中有很多方法可以实现私有和半私有属性,但它们与您如何创建构造函数及其赋予对象的方法有关,而不是您如何公开构造函数. "Namespace" 对象是关于如何公开构造函数的。
创建 "private" 属性的一种常见模式是在 构造函数中定义需要访问它们的方法 ,并在其中创建 "properties" 局部变量构造函数(所以它们根本不是真正的属性),像这样:
function SuperObject() {
var privateInformation;
this.method = function() {
// This can access `privateInformation`, which is completely
// hidden from outside the constructor
};
}
无论您是在 "namespacing" 模式中还是单独执行此操作都没有关系。
另一方面,私有 函数 会影响模式。我将在下面展示两者。
提供私有函数的一个相当常见的变体是使用函数创建对象,这也使您有机会创建私有函数:
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();
Is that mySuperObjectInNS still a constructor function? (For me it seems it is something else,even if I can intantiate objects from it.
是的。构造函数是任何希望您使用 new
的函数。
Is is a very bad very bad way of namespacing or is kind of ok?
使用对象作为伪命名空间是常见的做法。您还可以考虑各种 asynchronous module definition (AMD) 技术,这些技术在很大程度上使 "namespace" 对象变得不必要。
回复您的评论:
You defined a self-invoking function....which returns an an object?
它不是一个 self 调用函数,它是一个 inline 调用函数,但是,是的,它是一个 returns一个对象。
(if so I think parantheses are missing)
不,我们不需要任何不存在的括号,因为在您看到的其他地方使用外括号的唯一原因是告诉解析器单词 function
开始一个表达式而不是声明;我们在上面不需要它,因为我们已经在赋值的右侧,所以当遇到 function
时没有歧义。
Due to you proposed this way, is it a better way to define the ns?
"Better" 是一个主观术语。它为您提供了一个范围,您可以在其中定义您询问过的私有函数。
Whereas I often also saw the option: var = {} | someNSName;
What is this all about?
如果您有多个文件会向 "namespace" 添加内容(这很常见),那么您经常会在每个文件中看到:
var TheNamespace = TheNamespace || {};
所做的是声明变量 if 它之前没有被声明过,并为它分配一个空对象 if 它还没有。在加载的 first 文件中,会发生这种情况:
处理 var
并创建一个新变量 TheNamespace
,值为 undefined
.
处理 TheNameSpace = TheNameSpace || {}
分配:由于 undefined
是假的,curiously-powerful ||
operator 导致新的 {}
,它被分配给 TheNamespace.
当加载 下一个 文件时,会发生这种情况:
var
是空操作,因为变量已经存在。
处理了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 || {});
想在命名空间内定义一个函数构造函数。到目前为止,我定义构造函数的方式是一个没有 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();
....
问题:
- 在我看来,这一切都是关于定义对象字面量和 我最近会遇到麻烦我正在尝试定义"private" 该对象的属性。这个对吗?
- 那个mySuperObjectInNS还是构造函数吗? (对我来说 似乎是别的东西,即使我可以从中实例化对象。
- 这是一种非常糟糕的命名空间方式还是还可以?
It seems to me that this all is about defining an Object-Literal and I will come into trouble the latest I am trying to define "private" properties of that object. Is this correct?
"Private properties" 与使用对象进行命名空间无关。事实上,最初在回答这个问题时,我读作 "private functions" 因为 会 是相关的。
在JavaScript中有很多方法可以实现私有和半私有属性,但它们与您如何创建构造函数及其赋予对象的方法有关,而不是您如何公开构造函数. "Namespace" 对象是关于如何公开构造函数的。
创建 "private" 属性的一种常见模式是在 构造函数中定义需要访问它们的方法 ,并在其中创建 "properties" 局部变量构造函数(所以它们根本不是真正的属性),像这样:
function SuperObject() {
var privateInformation;
this.method = function() {
// This can access `privateInformation`, which is completely
// hidden from outside the constructor
};
}
无论您是在 "namespacing" 模式中还是单独执行此操作都没有关系。
另一方面,私有 函数 会影响模式。我将在下面展示两者。
提供私有函数的一个相当常见的变体是使用函数创建对象,这也使您有机会创建私有函数:
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();
Is that mySuperObjectInNS still a constructor function? (For me it seems it is something else,even if I can intantiate objects from it.
是的。构造函数是任何希望您使用 new
的函数。
Is is a very bad very bad way of namespacing or is kind of ok?
使用对象作为伪命名空间是常见的做法。您还可以考虑各种 asynchronous module definition (AMD) 技术,这些技术在很大程度上使 "namespace" 对象变得不必要。
回复您的评论:
You defined a self-invoking function....which returns an an object?
它不是一个 self 调用函数,它是一个 inline 调用函数,但是,是的,它是一个 returns一个对象。
(if so I think parantheses are missing)
不,我们不需要任何不存在的括号,因为在您看到的其他地方使用外括号的唯一原因是告诉解析器单词 function
开始一个表达式而不是声明;我们在上面不需要它,因为我们已经在赋值的右侧,所以当遇到 function
时没有歧义。
Due to you proposed this way, is it a better way to define the ns?
"Better" 是一个主观术语。它为您提供了一个范围,您可以在其中定义您询问过的私有函数。
Whereas I often also saw the option:
var = {} | someNSName;
What is this all about?
如果您有多个文件会向 "namespace" 添加内容(这很常见),那么您经常会在每个文件中看到:
var TheNamespace = TheNamespace || {};
所做的是声明变量 if 它之前没有被声明过,并为它分配一个空对象 if 它还没有。在加载的 first 文件中,会发生这种情况:
处理
var
并创建一个新变量TheNamespace
,值为undefined
.处理
TheNameSpace = TheNameSpace || {}
分配:由于undefined
是假的,curiously-powerful||
operator 导致新的{}
,它被分配给TheNamespace.
当加载 下一个 文件时,会发生这种情况:
var
是空操作,因为变量已经存在。处理了
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 || {});