2012-02-23 54 views
1

我正在嘗試JavaScript的繼承。基本上,我正在遵循this教程。爲什麼我們需要在JavaScript中調用父構造函數繼承

我看到,在那裏的代碼中,Person類被實例化了兩次。請看this fiddle

我所做的是註釋掉:

Person.call(this) 

而且繼承工作得很好。

在原始代碼中,行

Person.call(this) 

被使用。是否需要使用子範圍調用父構造函數?

請你也給一些解釋,我是OO JavaScript的新手。

非常感謝。

編輯:

我在小提琴代碼如下:

function Person(gender) { 
    this.gender = gender; 
    document.write('Person instantiated</br>'); 
} 

Person.prototype.walk = function(){ 
    document.write("is walking</br>"); 
}; 

Person.prototype.sayHello = function(){ 
    document.write("Hello</br>"); 
}; 

Person.prototype.sayGender = function(){ 
    document.write(this.gender + "</br>"); 
}; 



function Student() { 
    //Person.call(this); 
    document.write('Student instantiated</br>');   
} 
Student.prototype = new Person(); 

Student.prototype.constructor = Student; 

Student.prototype.sayHello = function(){ 
    document.write("Student says Hello</br>"); 
} 
Student.prototype.sayGoodBye = function(){ 
    document.write("Student says goodbye</br>"); 
} 


var student1 = new Student(); 
student1.sayHello(); 
student1.walk(); 
student1.sayGoodBye(); 

document.write(student1 instanceof Person); 
document.write("</br>"); 
document.write(student1 instanceof Student); 
+0

@ T.J.Crowder:很抱歉,如果我的問題的基調已經出了問題。我從來沒有打算過無禮。 – riship89 2012-02-23 09:00:47

+0

'@ hrishikeshp19':不,我認爲你沒有。 :-) – 2012-02-23 09:25:40

回答

1

運行,你只提供的示例調用人()構造函數一次在腳本初始執行期間,當行「Student.prototype = new Person();」被執行。

如果我們修改腳本創建第二個學生和設置從實例中分離:bit: http://jsfiddle.net/anacW/

function Person(gender) { 
    this.gender = gender; 
    document.write('Person instantiated</br>'); 
} 

Person.prototype.walk = function(){ 
    document.write("is walking</br>"); 
}; 

Person.prototype.sayHello = function(){ 
    document.write("Hello</br>"); 
}; 

Person.prototype.sayGender = function(){ 
    document.write(this.gender + "</br>"); 
}; 



function Student() { 
    //Person.call(this); 
    document.write('Student instantiated</br>');   
} 
Student.prototype = new Person(); 

Student.prototype.constructor = Student; 

Student.prototype.sayHello = function(){ 
    document.write("Student says Hello</br>"); 
} 
Student.prototype.sayGoodBye = function(){ 
    document.write("Student says goodbye</br>"); 
} 

document.write("*** Building student1 *** </br>"); 
var student1 = new Student(); 
student1.sayHello(); 
student1.walk(); 
student1.sayGoodBye(); 

document.write("*** Building student2 ***</br>"); 
var student2 = new Student(); 
student2.sayHello(); 
student2.walk(); 
student2.sayGoodBye(); 

document.write("*** InstanceOf Tests ***</br>"); 
document.write("student1 is Person?: " + (student1 instanceof Person)); 
document.write("</br>"); 
document.write("student1 is Student?: " + (student1 instanceof Student)); 
document.write("</br>"); 
document.write("student2 is Person?: " + (student2 instanceof Person)); 
document.write("</br>"); 
document.write("student2 is Student?: " + (student2 instanceof Student)); 

該代碼給出:

Person instantiated 
*** Building student1 *** 
Student instantiated 
Student says Hello 
is walking 
Student says goodbye 
*** Building student2 *** 
Student instantiated 
Student says Hello 
is walking 
Student says goodbye 
*** InstanceOf Tests *** 
student1 is Person?: true 
student1 is Student?: true 
student2 is Person?: true 
student2 is Student?: true 

,向您顯示Person構造函數只被調用一次,並且永遠不會通過實例化Student來調用。這可能是你的理想情況(我不知道足夠的javascript來告訴你它是否是'正確'的形式)。

+0

我不知道任何情況下,這是可取的;通常它會導致錯誤(只要示例不是太簡單)。該代碼構造有些情況,但不在oo繼承中。 – Bergi 2012-04-02 23:08:34

-1

在這裏,我如何做到這一點:

Foo = function() {} 
Foo.prototype.sayHello = function() { console.log("hello"); } 

Bar = function() {} 
Bar.prototype = new Foo(); 
Bar.prototype.sayBye = function() { console.log("bye"); } 

var oBar = new Bar(); 
oBar.sayHello(); // "hello" 
oBar.sayBye(); // "bye" 
+1

是的。但是,在這種方法中,Bar的構造函數從不被調用。因此,擁有任何對「酒吧」私密的東西都沒有意義。因此,Bar永遠不會被初始化,你所使用的只是Foo對象。 – riship89 2012-02-23 18:44:02

4

是的,你會需要它。在你的例子中,所有學生都具有相同的性別,只有一個人實例化,不管實例化學生的數量如何。

更好的方式是:

function Student() { 
    // gives this Student properties of one (new) Person: 
    Person.call(this); 
    document.write('Student instantiated</br>');   
} 
// does not create a Person, just makes Students have Person prototype features 
Student.prototype = Object.create(Person.prototype); 
+1

這個答案應該被接受。有人問我們爲什麼需要做'Person.call(this);'它回答了這個問題。嘗試在Person.call(this)之前放置一個'debugger',並且看到this'(Student)的值;你會發現它之前沒有'gender'屬性,但是一旦調用了'parent'就會得到它。 – 2013-02-04 07:23:21

相關問題