我们大多数人都知道JavaScript没有"私有"属性,但可以通过使用闭包来模拟该行为:
var Car = function () {
var name = 'Tesla';
var wheelCount = 4;
this.getName = function () {
return name;
};
this.getWheelCount = function () {
return wheelCount;
};
this.setName = function (newName) {
name = newName;
};
this.setWheelCount = function (newCount) {
wheelCount = newCount;
};
};
var myCar = new Car();
console.log(myCar.name); // undefined
对于了解JavaScript闭包如何工作的人来说,这一切都是有意义的。但是,以下内容可行:
myCar.name = 'Corvette';
console.log(myCar.name); // 'Corvette'
但是如果从原型中调用函数,则仍然使用封闭变量
console.log(myCar.getName()); // 'Tesla'
当您致电myCar.name
时,您正在向对象添加新属性。在this
定义中声明getName
(等)函数以区分Car
内的name
时,是否只是使用Car
的全部内容声明与myCar.name
?
我有一种感觉,我知道答案,但我想确定。另外,我认为这对其他人掌握JavaScript封装的工作原理是非常宝贵的。
答案 0 :(得分:1)
在您的示例中,car函数是一个构造函数。当使用new运算符调用构造函数时,会创建一个新对象并且"这个"绑定到该新对象。并且"这个"即使没有return语句也会从函数返回(与非构造函数不同,如果没有返回则返回undefined)
所以当你调用new Car()时,会创建一个新对象,并且#34;这个"在这个新对象中,新对象获得了你在Car函数中定义的4个函数(getName,getWheelCount,setName,setWheelCount)
Car函数中定义的名称变量不限于"这个",它与Car的功能范围有关。当汽车功能返回"这个",因为关闭getName()仍然可以访问函数的名称变量。
现在当你尝试myCar.name时,因为创建的新对象没有任何名为name的变量,所以它打印为undefined。
在执行myCar.name =' Corvette'时,由于在myCar中找不到名为name的属性,因此创建了名为" name"的新属性。和价值" Corvette" (javascript创建一个新属性,如果在写操作的情况下它还不存在,对于读操作原型链是遵循的)
但令人惊讶的是myCar.getName()仍会打印"特斯拉"而不是Corvette,因为虽然变量名是相同的,但是它们在不同的范围内.getName引用的那个是Car函数范围的一部分,并且通过Closure限制为getName,但名称(" corvette" )您添加的属于您创建的新对象。
"这个"的目的是将构造函数内定义的函数/变量添加到您将通过该构造函数创建的对象。
希望它有所帮助。
答案 1 :(得分:1)
在
this
定义中声明getName
(等)函数以区分{{1}中包含的名称时,是否只是使用Car
的全部内容声明与Car
?
是
myCar.name
(或this
)是您放置属性的对象(在本例中为所有这些方法)。如果要使用属性,则必须使用property accessor。
myCar
只是构造函数中的本地变量,可以通过对象方法的闭包来访问。
或者,回答你的标题问题:
如果包含变量,并且实例设置了具有相同名称的属性,则属性在哪里?
该属性在对象上 。它根本不会干扰变量,该变量位于var name
构造函数调用的范围中。