Почему ленивые геттеры работают с прототипами, а не с классами?

1

Рассмотрим следующий код:

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 тенью несуществующий сеттер.


Теперь рассмотрим тот же код, используя классы 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);

Причина этого не объясняется в этом ответе. Это потому, что мы находим свойство в цепочке прототипов и у него нет сеттера. Итак, почему не та же ошибка возникает при использовании обычных прототипов?

Примечание. Вы можете удалить строку с ключевым словом delete не влияя на поведение кода.

Теги:
class
ecmascript-6
setter
getter

1 ответ

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 в строгом режиме по умолчанию.

В неаккуратном режиме назначение не работает, но игнорируется, а значение правой стороны return из геттера. .fullname повторном .fullname к .fullname снова будет запущен геттер.

  • 0
    Имеет смысл. Тем не менее, я считаю, что это не должно быть ошибкой в строгом режиме.
  • 0
    @AaditMShah Почему ты веришь в это?
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню