我在Mozilla的JavaScripts教程中遇到过这个问题,我似乎无法理解它。我读了很多stackoverflow问题,但我找不到我的问题的答案。以下是代码段。
var createPet = function(name) {
var sex;
return {
setName: function(newName) {
name = newName;
},
getName: function() {
return name;
},
getSex: function() {
return sex;
},
setSex: function(newSex) {
if(typeof newSex == "string" && (newSex.toLowerCase() == "male" || newSex.toLowerCase() == "female")) {
sex = newSex;
}
}
}
}
var pet = createPet("Vivie");
var pet2 = createPet("Sam");
pet.getName(); // Vivie
pet2.getName(); // Sam
createPet
似乎只返回一个函数对象的映射,但是在任何地方都没有提到变量name
,但不知何故,pet
和pet2
表现得像一个类的对象使用名为name
的成员变量和一些成员函数,如getName()
,setName()
等。这是如何工作的?
答案 0 :(得分:3)
name
是createPet()
函数的参数。它与局部变量sex
的工作方式相同,并且表现为私有成员变量,只能在createPet()
内声明的函数访问。 name
被传递到createPet()
,但它也可以在createPet()
内设置,并且由于返回对象中的函数创建的闭包,它在createPet()
的执行中幸存这些都引用了name
参数。
答案 1 :(得分:0)
name
被定义为正式参数,如function( name /*<-- there it is */)
。
所以想一想:
= function( name ) {
var sex;
};
如:
= function() {
var name = arguments[0];
var sex;
}
确实,或者至少是有效的。
是的,createPet
会返回混杂闭包的愚蠢地图。事实上,你可以这样做并看到它仍然有效:
var a = createPet("Vivie");
var asd = a.setName;
asd("asd");
a.getName() //"asd"
这是因为该对象几乎无关紧要,它是承载数据而不是对象的函数。该对象只是一个功能(闭包)的哑图。
您也不会处理对象属性而是处理变量。你不能假装变量是对象属性,除非它是一个实际上不是变量的全局变量,而是全局对象的属性:
除此之外,整个模型都是倒退的。您的行为包含数据而不是包含行为的数据。
当然,您无需执行此操作,请参阅https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Details_of_the_Object_Model。