Javascript Module Pattern 和 new 关键字
Javascript Module Pattern and the new keyword
我了解了模块模式的基础知识及其使用闭包来允许私有成员,但我无法完全接受为什么下面的代码会这样做:
var Calculator = function() {
var priv = 0;
return {
changePriv: function() { priv++;},
printPriv: function() { console.log(priv);}
}
}
var myCalc = Calculator();
myCalc.printPriv();
myCalc.changePriv();
myCalc.printPriv();
var myOtherCalc = Calculator();
myCalc.printPriv();
控制台输出为
0
1
1
因此,此处有意省略new
关键字,第一个调用集myCalc
Calculator 对象。它以 priv
值 0 开始,递增,然后打印出新的priv
值 1。
但是 a)为什么下一次调用 Calculator()
最终返回对 SAME 对象的引用(如第二个"1"所示)?我知道我可以在这里使用new
并避免这种情况,但不明白为什么我必须这样做。这个函数不是使用对象文字语法本质上创建一个新对象然后返回它吗?b) 既然它似乎确实使用相同的函数堆栈空间(这甚至是在 JS 中思考它的正确方法吗?),为什么在返回对同一对象的引用之前,它不在过程中将priv
变量清零?
编辑:纠正了草率/愚蠢的错误(感谢scessor),即使不使用new
关键字,它现在也会输出一个新的/不同的计算器对象。所以这清除了 a) 和 b)。我由此产生的问题是"在调用模块模式构造函数时,我是否使用 new
是否重要。答案是,我想没关系(?(约瑟夫:见 http://jsfiddle.net/MvMvy/5/...无论哪种方式,实例运算符都不适用于模块模式。
您不输出其他计算器myOtherCalc
:如果要比较它们,请将第三个myCalc.printPriv();
替换为:
myOtherCalc.printPriv();
然后输出为:
0
1
0
您不需要使用 new
。
通常,如果您使用 new
,您希望得到的是您调用的构造函数的实例。在您的情况下,它不会,因为您手动返回了一个对象。这是没有意义的,并且会导致以后混淆用法的问题。很快,您可能会"实例测试"您的对象,并且会遇到这种"不匹配"。
而且你的代码中有一个错别字:
var myCalc = Calculator(); //create calculator
myCalc.printPriv(); //"myCalc" private is 0
myCalc.changePriv(); //increment
myCalc.printPriv(); //"myCalc" private is 1
var myOtherCalc = Calculator(); //another calculator
myCalc.printPriv(); ///but you printed "myCalc" again
与"新"运算符无关...在这里,您可以获得有关原型/构造函数的良好解释主题:http://en.wikibooks.org/wiki/JavaScript/Access_Control
然而,这是一个无意义的示例,你可以这样做,所以你只能通过getter和setter方法访问priv:
function Calculator2() {
var priv = 0;
this.public = 0;
this.getPriv = function(){
return priv;
}
this.setPriv = function(val){
priv = val;
}
}
Calculator2.prototype.changePriv = function(){
this.setPriv(this.getPriv()+1);
}
Calculator2.prototype.printPriv = function(){
console.log("priv = " + this.getPriv());
}
Calculator2.prototype.changePublic = function(){
this.public++;
}
Calculator2.prototype.printPublic = function(){
console.log(this.public);
}
在这种情况下,var priv 始终可以通过 getter 和 setter 方法访问,
在下一个示例中,您有一个私有 var className 和另一个公共 var __className:
<div id = "outputDiv" style="width:600px;height:400px;border:solid 1px #000"></div>
<script type="text/javascript">
//<![CDATA[
//脚本: var SomeClass = function(className) {
var __className__ = className;
this.__className__ = "'"public default className'"";
var someString = new String("");
this.setScopeText = function() { // void
someString = "A new instance of '"private [__classname__] : " +
__className__ + "'"" +
" has been created. Refering to [__className__]<br />" +
"A new instance of " +
this.__className__ +
" has been created. Refering to [this.__className__]";
return someString;
};
this.getScopeText= function (){
return someString;
}
this.setOutput = function(elementId, someString){
var outputPane = this.getSomePane(elementId);
outputPane.innerHTML += "<p>" + someString + "</p>";
}
this.getSomePane = function(elementId){
var outputP = document.getElementById(elementId);
return outputP;
}
}
SomeClass.prototype.changeClassNameVariable = function( str ){
this.__className__ = str;
}
结束声明。
//测试:
var sc = new SomeClass("foo");
sc.setOutput("outputDiv",sc.__className__);
sc.setOutput("outputDiv",sc.setScopeText());
sc.setOutput("outputDiv",sc.getSomePane("outputDiv"));
sc.__className__ = "'"Some name'"";
sc.setOutput("outputDiv",sc.__className__);
sc.setOutput("outputDiv",sc.setScopeText());
sc.changeClassNameVariable("bar");
sc.setOutput("outputDiv",sc.__className__);
sc.setOutput("outputDiv",sc.setScopeText());
结束 JavaScript 和 CDATA 部分
//]]>
</script>
输出 "div:outputDiv" :
"公共默认类名"
已创建"private [classname] : foo"的新实例。参考 [类名]已创建"公共默认类名"的新实例。参考[这个。类名]
[object HTMLDivElement]
"某个名字"
已创建"private [classname] : foo"的新实例。参考 [类名]已创建"某个名称"的新实例。参考[这个。类名]
酒吧
已创建"private [classname] : foo"的新实例。参考 [类名]已创建柱线的新实例。参考[这个。类名]
->构造函数中声明的类名永远不会改变!->这个。className 或 SomeClass.prototype。类名是公共的,可以更改。
我希望这可能有助于更清楚地理解链条和我的评论......
- 如何在不使用 new 关键字的情况下从函数创建对象
- “new”关键字是在构造对象时自动设置“constructor”属性的唯一方法吗
- 使用“new”关键字创建的对象和使用“Object.create”创建的对象给出不同的结果
- JavaScript:古代代码使用“new”关键字启动简单对象.为什么
- 将 JavaScript new 关键字与可变长度参数数组一起使用
- 如何判断对象是使用“Object.create”还是使用文字语法/“new”关键字创建的
- 在 anthor object 中使用 Object 方法,而无需在 javascript 中使用 new 关键字
- 使用“new”关键字的Javascript函数表达式视为“静态”是否正确?
- 在javascript中使用“new”关键字的替代方案是什么?
- JavaScript 'new' 关键字,带或不带 '()'
- Javascript Module Pattern 和 new 关键字
- Javascript中“new”关键字的限制
- javascript初始化一个没有new关键字的对象
- 闭包可以使用new关键字和区别,例如,在创建新对象/类时
- 函数中的Javascript“new”关键字
- JavaScript原型继承和“new”关键字
- 在Javascript中使用instanceof自定义对象而不使用new关键字
- 如何给一个对象's与javascript中的new关键字的属性和方法
- 为什么函数在构造函数中声明时不使用new关键字
- JavaScript避免new关键字