Wednesday, June 5, 2024
 Popular · Latest · Hot · Upcoming
179
rated 0 times [  186] [ 7]  / answers: 1 / hits: 131161  / 7 Years ago, wed, may 31, 2017, 12:00:00

The following code will throw an error only for the name property.
It could be fixed by specifying name property as writable in Object.create arguments but I'm trying to understand why is this happening(and maybe there is a more elegant way to fix it).





var BaseClass = function (data) {
Object.assign(this, data);
}

var ExtendedClass = function () {
BaseClass.apply(this, arguments);
}

ExtendedClass.prototype = Object.create(BaseClass);

console.log(new ExtendedClass({ type: 'foo' }));
new ExtendedClass({ name: 'foo' });




More From » oop

 Answers
13

You cannot modify the name property of a function. The descriptor says it is not writable...





var BaseClass = function (data) {
Object.assign(this, data);
};

console.log(Object.getOwnPropertyDescriptor(BaseClass, 'name'));





But since it is configurable, you could use Object.defineProperty().





var BaseClass = function (data) {
Object.assign(this, data);
};

Object.defineProperty(BaseClass, 'name', {
writable: true,
value: 'Foo'
});

console.log(BaseClass.name);








EDIT



I'm back! So... As I said previously in comments, I think I have identified your problem. I answered a bit too fast and did not see that your ES5 inheritance is wrong.



ExtendedClass.prototype = Object.create(BaseClass); is not what you want to do. Doing so means the prototype of ExtendedClass becomes a constructor function. This obviously generates an unexpected behavior.





function BaseClass(data) {
console.log(this instanceof BaseClass); // this is not an instance of BaseClass
console.log(this instanceof Function); // this is a function
console.log(this.name); // this is BaseClass

Object.assign(this, data);
}

function ExtendedClass() {
BaseClass.apply(this, arguments);
}
ExtendedClass.prototype = Object.create(BaseClass);

new ExtendedClass({ type: 'foo' });





In your code, this is a function and refers to BaseClass. That is why you are not allowed to modify its name...



In fact, when working with inheritance in JavaScript, you generally need these two lines:



ExtendedClass.prototype = Object.create(BaseClass.prototype);
ExtendedClass.prototype.constructor = ExtendedClass;


Here is a valid implementation:





function BaseClass(data) {
console.log(this instanceof BaseClass); // this is an instance of BaseClass
console.log(this instanceof Function); // this is not a function
console.log(this.name); // this has no name yet

Object.assign(this, data);
}

function ExtendedClass() {
BaseClass.apply(this, arguments);
}
ExtendedClass.prototype = Object.create(BaseClass.prototype);
ExtendedClass.prototype.constructor = ExtendedClass;

var instance = new ExtendedClass({ name: 'foo' });

console.log(instance.name); // foo
console.log(BaseClass.name); // BaseClass
console.log(ExtendedClass.name); // ExtendedClass




[#57608] Sunday, May 28, 2017, 7 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
averyc

Total Points: 102
Total Questions: 113
Total Answers: 89

Location: Taiwan
Member since Mon, Sep 6, 2021
3 Years ago
;