Reputation: 10938
In this related question, the answer for setting a constructor is like so:
function OldClass() {
alert("old class with incomplete constructor")
}
function ChangedClass(){
alert('new class with same prototype and more complete constructor');
}
ChangedClass.prototype = OldClass.prototype;
var theClassIWant = new ChangedClass();
This is not really setting the constructor, it's making a new object and inheriting the prototype. How can I set the constructor of an Object without changing to a new Object? Is it possible?
P.S. I want something like this:
//non working code
var Foo = function() {}
Foo.prototype.constructor = function(bar_val) {
this.bar = bar_val;
}
var fez = new Foo("cat")
console.log(fez.bar); // outputs: cat;
Upvotes: 1
Views: 81
Reputation: 337
myClass = {
constructor: function(text){
console.log(text);
}
}
let ob = Object.create(myClass);
ob.constructor("old constructor "); //Output: old constructor
myClass.constructor = function(){
console.log("new constructor ")
}
ob.constructor(); //Output: new constructor
You can do this with every property or function of a class.
Watch this Video here. It explains it perfectly.
Upvotes: 2
Reputation: 13838
constructor
is a property of the constructor function's prototype
, which points to the function itself by default.
When you modify Foo.prototype.constructor
, this property points to another function. However, the constructor function Foo
remains. So when you create an object, you are still instantiate the constructor function Foo
, not the one Foo.prototype.constructor
points to.
This is why your code doesn't work. Then let's talk why we need to change the constructor and how to.
In ES5 and before, we take advantage of prototype to simulate a class inheritance mechanism. Which looks like this:
// parent class
function Person(name) {
this.name = name
}
// define parent method
Person.prototype.say = function() {
console.log(this.name)
}
// child class
function Coder(name, major) {
Person.call(this, name) // inherits parent properties
this.job = 'Coding'
this.major = major
}
// inherits properties and methods from parent prototype
Coder.prototype = new Person()
// define child method
Coder.prototype.work = function() {
console.log('I write ' + this.major)
}
// instantiate a child object
var me = new Coder('Leo', 'JavaScript')
console.log(me) // {name: "Leo", job: "Coding", major: "JavaScript"}
Everything looks perfect, but there a problem:
console.log(me.constructor) // Person
What? Isn't me
constructed with Coder
? Why?
Go back to the first line of this answer, read it again: constructor
is a property of the constructor function's prototype
.
Originally Coder.prototype.constructor
is Coder
itself. But with this line: Coder.prototype = new Person()
, it got changed. Coder.prototype.constructor
now equals Person.prototype.constructor
, which is Person
.
Well, some would say, try instanceof
. Yes, that works:
me instanceof Coder // true
But it's also true
for Person
, because Coder
is a sub class of it:
me instanceof Person // true
This doesn't make sense so we need to fix the constructor problem. That's why we use Coder.prototype.constructor = Coder
after Coder.prototype = new Person()
, to get back the original constructor.
Full code looks like this:
// parent class
function Person(name) {
this.name = name
}
Person.prototype.say = function() {
console.log(this.name)
}
// child class
function Coder(name, major) {
Person.call(this, name) // inherits parent class
this.job = 'Coding'
this.major = major
}
Coder.prototype = new Person() // inherits parent's prototype
Coder.prototype.constructor = Coder // get back constructor
Coder.prototype.work = function() {
console.log('I write ' + this.major)
}
Upvotes: 2