为什么使用 getters/setters 的 Es6 类中的 Memoization 不起作用?

我在 Es6 类中遇到了一个关于 getter 和 setter 的奇怪问题。我想在 getter 属性上应用 memoization 的概念,一切似乎都很完美,但不是在严格模式下。


'use strict';


class obj {

    get name(){

        //memozation

        delete this.name;

        return this.name = "Ahmad";

    }

}

const o1 = new obj();

console.log(o1.name);

#output:未捕获的 TypeError:设置 getter-only 属性“name”


我尝试使用普通的 javascript 对象字面量实现相同的代码,并且效果很好:


'use strict';

    const x1 = {

        get name(){

            //memozation

            delete this.name;

            return this.name = "Ahmad";

        }

    }

    

console.log(x1.name); //#output: Ahmad

但在我发布这个问题之前,您可能想知道我是否尝试过使用 setter,事实上,是的,这实际上是 MDN HERE 上提到的内容,


但问题是,即使在使用 setter 之后,我也会看到另一个奇怪的问题:这是带有 setter 的代码:


'use strict';


class obj {

    get name(){

        //memozation

        delete this.name;

        return this.name = "Ahmad";

    }

    set name(value){

        this.name = value;

    }

}

const o1 = new obj();

console.log(o1.name);

#output:未捕获错误:未定义


请注意:我正在使用严格模式,并且正在 Mozilla firefox 上调试我的代码。


我该如何解决这个问题?这是什么原因呢?


HUX布斯
浏览 113回答 1
1回答

森林海

问题delete obj[prop]是只有prop直接在. _ obj如果属性在内部原型上,它不会删除该属性。再举个例子:const obj = Object.create({ prop: 'val' });delete obj.prop;console.log(obj);在您的情况下,name是原型上的一个属性:class obj {    get name(){结果name仅存在于 上obj.prototype,但不直接存在于o1实例上。Object.defineProperty修复它的一种方法是在 getter 内部使用,将属性直接放在实例上,以便this.name对该实例的进一步引用直接在实例上引用该属性,而单独使用 getter:'use strict';class obj {    get name(){        console.log('getter invoked');        Object.defineProperty(this, 'name', { value: "Ahmad" });        return this.name;    }}const o1 = new obj();console.log(o1.name);console.log(o1.name);或者,也可以使用二传手:'use strict';class obj {    defineName(value) {        Object.defineProperty(this, 'name', { value, writable: true });        return this.name;    }    get name(){        console.log('getter invoked');        return this.defineName("Ahmad");    }    set name(value) {        console.log('setter invoked');        return this.defineName(value);    }}const o1 = new obj();o1.name = 'foo';console.log(o1.name);console.log(o1.name);
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript