请考虑以下代码:
function Outer(){
function Inner(){
var private="something";
this.method = function(){
//some code here
};
}
var inner = new Inner(); //Why does this line not throw an error?
alert(inner.private); // not accessible here
inner.method();//no errors here
}
我无法理解为什么method()调用不会抛出错误而变量引用会抛出错误?我理解变量的范围只在声明它们的函数中?但是功能的范围呢?
答案 0 :(得分:3)
没有什么复杂的,它与数据类型无关。
new Inner()
创建一个新对象。您正在构造函数
this.method = function(){...};
另一方面,没有这样的属性private
。你永远不会this.private = ...;
。 private
只是Inner
函数的本地变量。
这是另一个与你的代码等效的例子,但希望更清楚:
function createObject() {
var someVariable = '42';
var obj = {};
obj.foo = 'bar';
return obj;
}
var myObject = createObject();
// works, since we assigned the property to the object
console.log(myObject.foo);
// does not work, we never assigned such a property to the object
console.log(myObject.someVariable);
在createObject
内部声明了两个变量,someVariable
和obj
。 obj
是一个对象,我们为它分配一个属性并从函数返回它。 someVariable
与对象无关,但可以在函数中用于其他目的。
答案 1 :(得分:1)
line var inner = new Inner()确实会抛出错误,因为内部未定义,它只能在外部函数的主体内访问。
inner.private不能作为inner的属性访问,因为它是closure variable。所以(new Inner())。private不存在。 (私有似乎是JS中的关键字,所以我在示例代码中将其更改为priv)
它可以在Inner函数体中访问,因为函数体内的代码保持对闭包变量的引用。
function Inner(){
var priv="something";
this.method = function(){//wrong, should declare as prototype
console.log("private from within Inner function body:"
,priv)
};
}
var inner = new Inner();
console.log(inner.priv); //=undefined
inner.method();//=something
具有许多实例的对象的函数属性;像Inner可以有很多例子:var a = new Inner(); var b = new Inner()...不应该用这个来定义。你应该使用原型代替。
当您使用原型时,您不能在原型函数中使用私有变量,因为私有(闭包)变量只能在主函数体中访问。这就是为什么许多开发人员使用_private
或private_
来表明它是私有的,因为JavaScript没有一个很好的方法来使成员变得私有而不会弄乱原型。
function Inner(){
var priv="private";//wrong
this._priv="private"
}
Inner.prototype.method=function(){
//cannot access priv
console.log(this._priv);//no problem
}
可能有一种情况,您可以通过这种方式使用私有,即只有一个对象实例。
var Mediator=(function(){
var events={};//private, other code can't mess this up
return{
addEvent:function(eventName){
events[eventName]=(events[eventName])?
events[eventName]:[];
},
addLisener:function(eventName,func){
events[eventName].push(func);
return events[eventName].length-1;
}
//more stuff like removeListener, trigger ...
}
})()
您可以阅读有关原型in this basic example的信息。您可以使用firebug控制台在Chrome或Firefox中运行代码。按F12打开它并粘贴控制台中该链接的代码。然后根据需要调整它,看看你是否得到了预期的输出并理解JS中的原型。