How Do I Call An Inherited Javascript Constructor With Parameters?
Solution 1:
Well, a way that you can re-use the logic of the Person
constructor is invoking it with call
or apply
, for example:
functionPerson(gender) {
this.gender = gender;
}
functionStudent(gender) {
Person.apply(this, arguments);
}
Student.prototype = newPerson(); // make Student inherit from a Person objectStudent.prototype.constructor = Student; // fix constructor propertyvar foo = newStudent('male');
foo.gender; // "male"
foo instanceofStudent; // true
foo instanceofPerson; // true
If you want to prevent the execution of the Person
constructor when is called without arguments (like in the line: Student.prototype = new Person();
), you can detect it, e.g.:
functionPerson(gender) {
if (arguments.length == 0) return; // don't do anythingthis.gender = gender;
}
Solution 2:
Accepted answer seems to be incorrect. Based on what Mozilla says about OO JavaScript, correct way to do it is:
varPerson = function(firstName) {
this.firstName = firstName;
};
functionStudent(firstName, subject) {
// Call the parent constructor, making sure (using Function#call)// that "this" is set correctly during the callPerson.call(this, firstName);
// Initialize our Student-specific propertiesthis.subject = subject;
};
// Create a Student.prototype object that inherits from Person.prototype.// Note: A common error here is to use "new Person()" to create the// Student.prototype. That's incorrect for several reasons, not least // that we don't have anything to give Person for the "firstName" // argument. The correct place to call Person is above, where we call // it from Student.Student.prototype = Object.create(Person.prototype); // See note below// Set the "constructor" property to refer to StudentStudent.prototype.constructor = Student;
// Example usage:var student1 = newStudent("Janet", "Applied Physics");
As you can clearly see, Mozilla specifies that it is a common error to use "new Person()" to create the Student.prototype. Hence accepted answer is misleading.
I have actually tested this in my ongoing project and Mozilla's way is correct, while above answer does not work.
Solution 3:
// define the Person ClassfunctionPerson(name) {
this.personname = name;
}
Person.prototype.walk = function(){};
Person.prototype.sayHello = function(){
alert (this.personname );
};
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/constructor
The full code:
<script>// define the Person ClassfunctionPerson(name) {
this.personname = name;
}
Person.prototype.walk = function(){};
Person.prototype.sayHello = function(){
alert (this.personname );
};
// define the Student classfunctionStudent() {}
// inherit PersonStudent.prototype = newPerson("test");
// correct the constructor pointer because it points to PersonStudent.prototype.constructor = Student;
// replace the sayHello methodStudent.prototype.sayHello = function(){
alert('hi, I am a student and my name is \'' + this.personname + '\'' );
}
// add sayGoodBye methodStudent.prototype.sayGoodBye = function(){
alert('goodBye');
}
var student1 = newStudent();
student1.sayHello();
student1.sayGoodBye();
</script>
Solution 4:
By all other comments I created an example which works for me. Since I did not use prototype explicitly I hope I am not missing an important point.
// variable for tracking instantiations and checking the uniqueness of the objectsvar instances = 0;
var Generic = function() {
this.instanceId = ++instances;
this.toString = function() {return'Generic [iid='+ this.instanceId +']'};
console.log('constructor-invoke: Generic ('+ this.instanceId +')');
};
var SpecificName = function(inName) {
Generic.call(this);
this.getName = function() { return inName; };
var superToString = this.toString.bind(this); // binds the inner function 'this' to this SpecificName instancethis.toString = function() {
return'SpecificName [iid='+ this.instanceId +', name='+ this.getName() +', super.toString='+ superToString() +']'
}
console.log('constructor-invoke: SpecificName ('+ this.instanceId +')');
};
var SpecificNames = function(inFirstName, inLastName) {
SpecificName.call(this, inLastName +', '+ inFirstName );
var superToString = this.toString.bind(this);
this.toString = function() {
return'SpecificNames [iid='+ this.instanceId +', name='+ this.getName() +', super.toString='+ superToString() +']'
}
console.log('constructor-invoke: SpecificNames ('+ this.instanceId +')');
};
var g = new Generic();
var sn = new SpecificName('Run Forest Run');
var sns = new SpecificNames('Forest','Gump');
console.log('g: '+ g.toString());
console.log('sn: '+ sn.toString());
console.log('sns: '+ sns.toString());
leads to this output:
constructor-invoke: Generic (1)
constructor-invoke: Generic (2)
constructor-invoke: SpecificName (2)
constructor-invoke: Generic (3)
constructor-invoke: SpecificName (3)
constructor-invoke: SpecificNames (3)
g: Generic [iid=1]
sn: SpecificName [iid=2, name=Run Forest Run, super.toString=Generic [iid=2]]
sns: SpecificNames [iid=3, name=Gump, Forest, super.toString=SpecificName [iid=3, name=Gump, Forest, super.toString=Generic [iid=3]]]
Post a Comment for "How Do I Call An Inherited Javascript Constructor With Parameters?"