构造函数,getter和setter方法中的Object.defineProperty

时间:2016-10-19 21:43:06

标签: javascript

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 ,因为使用同名的局部变量和对象属性更加令人困惑。

我怀疑这段代码是按预期工作的,但它让我感到困惑,甚至是它正在做的事情。

  1. 据我所知,它正在构造函数中使用Object.defineProperty在新创建的名为“name”的实例上创建一个属性。

  2. getter方法返回 xname ,然后 xname 在该行之后超出范围:var One = new Person(“Mark”);以后如何在代码对象的One getter中设法返回 xname 的值

  3. xname 的值,因为如果我更改了getter方法以返回 name ,就像它应该工作一样,引擎报告错误名称未定义。 (get:function(){return name;})

  4. 更不用说setter方法根本不起作用了。如果我编码One.name =“Mickey”,One.name仍然设置为“Mark”。

  5. 没有将.name赋值给.name或者有,但是我没有看到它?!

1 个答案:

答案 0 :(得分:0)

  

getter方法返回xnamexname超出范围后的行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




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

更多阅读:

相关问题