构造函数、getter和setter方法中的Object.defineProperty
Object.defineProperty in constructor, getter and setter method
这里问的是完全相同的问题在构造函数中定义属性,但我不觉得答案是令人满意的。代码是从"The Principles of Object Oriented 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
我已经将参数name修改为xname,因为使用相同名称的局部变量和对象属性会更加混乱。
我怀疑这段代码是否按预期工作,但它甚至让我感到困惑,它正在做一些事情。
我知道它是在构造函数中使用Object.defineProperty来为新创建的实例创建一个名为"name"的属性。
getter方法返回xname,然而xname在行之后超出了作用域:如何在代码对象的一个getter管理返回xname的值??
并且xname的值,因为如果我更改getter方法返回name,就像它应该工作一样,引擎报告错误name未定义。(get: function(){返回name;})
更不用说setter方法根本不起作用了。如果我编码One.name = "Mickey", One.name仍然设置为"Mark"
没有xname赋值给。name,或者有,但我没有看到?!
getter方法返回
xname
,然而xname
在行之后超出范围:var One = new Person("Mark");
如何在代码对象的一个getter管理返回xname
的值??
因为仍然在的作用域中。是的,Person
函数已经返回,但是因为有些函数关闭了调用Person
的上下文,所以在该上下文中定义的参数和变量仍然可以被这些函数访问。
当你调用一个函数时,在规范术语中创建一个对象,该对象包含函数参数的"绑定"(把它们想象成属性),调用中的局部变量等。在调用该函数期间创建的任何函数都会维护对该对象的引用,因此即使在函数返回之后,该对象仍然存在。这是JavaScript闭包的基础。这就是为什么你可以继续使用xname
,即使Person
已经从调用中返回,在该实例上创建getter和setter。
我已将参数名称修改为xname,因为使用相同名称的局部变量和对象属性会更加混乱。
你只在getter中做过;你需要在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);
};
}
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
函数时,它使用createClosure
在创建该函数时接收到的arg
参数,即使createClosure
已经返回。c1
(和c2
)都有一个对创建它们的上下文的引用。它们"关闭"了与创建它们的调用相关的arg
。
更多阅读:
- 闭包是如何工作的?
- 闭包并不复杂在我贫乏的小博客(选择标题是因为它们看起来复杂,但实际上很简单)
- 函数未在Object.keys或Object.getOwnPropertyNames下列出,但可以调用
- delete在Object上效率低下,但在DOM Element's的数据属性,与null out相比
- 有没有一种方法可以列出Ember.Object的所有绑定
- 如何取消object.prototypes javascript的一个函数
- 为什么是文档.旧版应用程序中的DOM-object.properties为null
- 将*.js文件的内容放入Object中
- Object.prototype using 'this'
- 使用Object.create()的角度服务继承
- 如何使用object.assign()从其他对象引用基本对象属性
- 循环的数组推入在Object容器中具有不同的值
- reducers在redux中得到Function not Object,what'it’他错了
- JSON.stringify和Object.keys在同一个对象上产生不同的结果
- 在使用object.create创建的对象中使用super
- Join架构验证:Join.object定义数组中的有效键
- jquery打印[object XMLDocument]而不是文件内容
- ExtJS 4 Object.prototype fail
- JavaScript-从对象数组中输出随机OBJECT
- 为什么“{}+1”在Chrome和Firefox中排名第一,而字符串'[object object]1'
- 什么是“;原型;通过JavaScript中的Object Literal Notation创建的对象的链接
- 如何在Node.js控制台中发现Object API