2010-08-30 15 views

Antwort

38

Nun, eine Möglichkeit, dass Sie die Logik des Person Konstruktor wiederverwenden kann, ist es mit call Aufruf oder apply, zum Beispiel:

function Person(gender) { 
    this.gender = gender; 
} 

function Student(gender) { 
    Person.apply(this, arguments); 
} 
Student.prototype = new Person(); // make Student inherit from a Person object 
Student.prototype.constructor = Student; // fix constructor property 

var foo = new Student('male'); 
foo.gender;    // "male" 
foo instanceof Student; // true 
foo instanceof Person; // true 

Wenn Sie die Ausführung des Person Konstruktor verhindern wollen, wenn sie ohne Argumente (wie in der Zeile: Student.prototype = new Person();) aufgerufen wird, können Sie es erkennen, zB:

function Person(gender) { 
    if (arguments.length == 0) return; // don't do anything 
    this.gender = gender; 
} 
+1

@CMS Für den zweiten Teil 'if (arguments.length == 0) return;' gibt es eine Möglichkeit, Konstruktoren zu behandeln, bei denen die Argumente NICHT benötigt werden? Muss ich in dieser Situation den Konstruktor aufrufen? –

+0

Ich habe viele verschiedene Methoden ausprobiert ('Object.create',' Person.prototype', Temp-Funktionen ...), aber alle von ihnen scheitern oder haben Bugs (undefinierte Eigenschaften, verdeckte, etc.). Danke für diese Antwort, endlich eine, die wirklich funktioniert! – TheBronx

0
// define the Person Class 
function Person(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


Der vollständige Code:

<script> 
// define the Person Class 
function Person(name) { 
    this.personname = name; 
} 

Person.prototype.walk = function(){}; 
Person.prototype.sayHello = function(){ 
    alert (this.personname); 
}; 

// define the Student class 
function Student() {} 

// inherit Person 
Student.prototype = new Person("test"); 

// correct the constructor pointer because it points to Person 
Student.prototype.constructor = Student; 

// replace the sayHello method 
Student.prototype.sayHello = function(){ 
    alert('hi, I am a student and my name is \'' + this.personname + '\''); 
} 

// add sayGoodBye method 
Student.prototype.sayGoodBye = function(){ 
    alert('goodBye'); 
} 

var student1 = new Student(); 
student1.sayHello(); 
student1.sayGoodBye(); 
</script> 
+1

Ich denke, das funktioniert gut, wenn man immer „test“ als die Person benennen will, aber das ist nicht das, was ich meine, wenn ich es von der rufen fragen Studentenkonstruktor. – kgarske

9

akzeptierte Antwort scheint falsch zu sein . richtige Art und Weise auf das, was Mozilla says about OO JavaScript, es zu tun ist:

var Person = function(firstName) { 
    this.firstName = firstName; 
}; 

function Student(firstName, subject) { 
    // Call the parent constructor, making sure (using Function#call) 
    // that "this" is set correctly during the call 
    Person.call(this, firstName); 

    // Initialize our Student-specific properties 
    this.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 Student 
Student.prototype.constructor = Student; 

// Example usage: 
var student1 = new Student("Janet", "Applied Physics"); 

Wie man deutlich sehen kann, Mozilla gibt an, dass es ein häufiger Fehler ist „new Person()“ zu verwenden, um die Student.prototype zu erstellen. Daher ist die angenommene Antwort irreführend.

Ich habe dies tatsächlich in meinem laufenden Projekt getestet und Mozilla ist richtig, während obige Antwort nicht funktioniert.

0

Durch alle anderen Kommentare habe ich ein Beispiel erstellt, das für mich funktioniert. Da ich den Prototyp nicht explizit verwendet habe, hoffe ich, dass mir ein wichtiger Punkt nicht entgeht.

// variable for tracking instantiations and checking the uniqueness of the objects 
var 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 instance 
    this.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()); 

führt zu dieser Ausgabe:

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]]] 
Verwandte Themen