在define property in constructor处提出了完全相同的问题,但我觉得答案并不令人满意。 该代码是从“面向对象的JavaScript的原理”一书中复制而来,只需稍作修改即可使问题更加清晰。
function Person(xname) {
Object.defineProperty(this, "name", {
get: function() {
return xname;
},
set: function(newName) {
name = newName;
},
configurable: true,
enumerable: true
});
this.sayName = function() {
console.log(this.name);
};
}
var One = new Person("Mark");
One.sayName();
console.log(One.name);
//output:
//Mark
//Mark
我已将参数名称修改为 xname ,因为使用同名的局部变量和对象属性更加令人困惑。
我怀疑这段代码是按预期工作的,但它让我感到困惑,甚至是它正在做的事情。
据我所知,它正在构造函数中使用Object.defineProperty在新创建的名为“name”的实例上创建一个属性。
getter方法返回 xname ,然后 xname 在该行之后超出范围:var One = new Person(“Mark”);以后如何在代码对象的One getter中设法返回 xname 的值
是 xname 的值,因为如果我更改了getter方法以返回 name ,就像它应该工作一样,引擎报告错误名称未定义。 (get:function(){return name;})
更不用说setter方法根本不起作用了。如果我编码One.name =“Mickey”,One.name仍然设置为“Mark”。
没有将.name赋值给.name或者有,但是我没有看到它?!
答案 0 :(得分:0)
getter方法返回
xname
但xname
超出范围后的行var One = new Person("Mark");
以后如何在代码对象的一个getter中设置返回值xname
...
因为 仍在其使用范围内。是的,Person
函数已经返回,但由于函数在Person
调用的上下文中关闭,因此这些函数仍然可以访问在该上下文中定义的参数和变量。
调用函数时,在规范术语中,会创建一个包含"绑定" (将它们视为属性)用于函数的参数,调用中的局部变量等。在对函数的调用期间创建的任何函数都维护对该对象的引用,因此即使在函数之后对象仍然存在已经回来了。这是JavaScript中闭包的基础。这就是为什么即使在xname
从调用返回的Person
创建该实例上的getter和setter之后仍然可以继续使用function Person(xname) {
Object.defineProperty(this, "name", {
get: function() {
return xname;
},
set: function(newName) {
xname = newName; // *** Here too
},
configurable: true,
enumerable: true
});
this.sayName = function() {
console.log(this.name);
};
}
的原因。
我已经将参数名称修改为xname,因为使用具有相同名称的局部变量和对象属性更加令人困惑。
你只是在吸气器中做到了这一点;你需要在getter 和 setter中完成它才能正常工作:
Object.defineProperty
new
内容(事实上,甚至function createClosure(arg) {
return function() {
console.log(arg);
};
}
var c1 = createClosure("one");
var c2 = createClosure("two");
c1(); // "one"
c2(); // "two"
c1(); // still "one"
c2(); // still "two"
)都有点不合适。你所看到的基本问题是闭包是如何工作的,所以让我们看一个更简单的例子:
c1

正如您所看到的,当我们调用c2
或arg
函数时,它会使用创建该函数时createClosure
收到的createClosure
参数,即使{ {1}}已退回。 c1
(和c2
)每个都引用了创建它们的上下文。他们"关闭" arg
与创建它们的电话有关。
更多阅读: