Consider the following code:
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 works because the property assignment on this
shadows the non-existent setter.
Now, consider the same code using ES6 classes:
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);
The reason why it doesn't work is explained in the this answer . It's because we find the property in the prototype chain and it doesn't have a setter. So, why isn't the same error thrown when we use regular prototypes?
Note: You can delete the line with the delete
keyword without affecting the behavior of the code.
I do get the same error with the first code:
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
It's just that class
code is in strict mode by default.
In sloppy mode, the assignment doesn't work but is ignored and the right hand side value is return
ed from the getter. Accessing .fullname
again would run the getter again.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.