为什么懒惰的getter工作原型而不是类?

时间:2018-06-12 10:17:01

标签: javascript class ecmascript-6 setter getter

请考虑以下代码:



const defclass = prototype => {
    const constructor = prototype.constructor;
    constructor.prototype = prototype;
    return constructor;
};

const Person = defclass({
    constructor: function Person(firstname, lastname) {
        this.firstname = firstname;
        this.lastname  = lastname;
    },
    get fullname() {
        delete this.fullname; // doesn't delete on instances
        return this.fullname = this.firstname + " " + this.lastname;
    }
});

const john = new Person("John", "Doe");
const jane = new Person("Jane", "Doe");

console.log(john.fullname); // John Doe
console.log(jane.fullname); // Jane Doe




这是有效的,因为this上的属性赋值会影响不存在的setter。

现在,考虑使用ES6类的相同代码:



class Person {
    constructor(firstname, lastname) {
        this.firstname = firstname;
        this.lastname  = lastname;
    }

    get fullname() {
        delete this.fullname; // doesn't delete on instances
        return this.fullname = this.firstname + " " + this.lastname;
    }
}

const john = new Person("John", "Doe");
const jane = new Person("Jane", "Doe");

console.log(john.fullname); // throws an error because there is no setter
console.log(jane.fullname);




this answer解释了它不起作用的原因。这是因为我们在原型链中找到了属性并且它没有设置器。那么,当我们使用常规原型时,为什么不会抛出相同的错误?

注意:您可以使用delete关键字删除该行,而不会影响代码的行为。

1 个答案:

答案 0 :(得分:2)

使用第一个代码获得相同的错误:

const defclass = prototype => {
    const constructor = prototype.constructor;
    constructor.prototype = prototype;
    return constructor;
};

const Person = defclass({
    constructor: function Person(firstname, lastname) {
        this.firstname = firstname;
        this.lastname  = lastname;
    },
    get fullname() {
        "use strict";
//      ^^^^^^^^^^^^
        return this.fullname = this.firstname + " " + this.lastname;
    }
});

const john = new Person("John", "Doe");
const jane = new Person("Jane", "Doe");

console.log(john.fullname); // John Doe
console.log(jane.fullname); // Jane Doe

默认情况下,class代码只在strict mode

在草率模式下,分配不起作用但被忽略,右侧值从getter开始return。再次访问.fullname会再次运行getter。