2012-02-23 14 views
1

JavaScript継承を試しています。基本的には、私はthisチュートリアルに従っています。JavaScriptの親コンストラクタを呼び出す必要があるのはなぜですか?継承

私はそこのコードで、Personクラスが2回インスタンス化されていることが分かります。 this fiddleをご覧ください。私が何をしたか

はコメントアウトです:

Person.call(this) 

と継承がうまく働いています。元のコードで

Person.call(this) 

ラインが使用されます。子スコープの親コンストラクタを呼び出す必要がありますか?

私はOO JavaScriptを初めて使用しています。

ありがとうございます。

EDIT:次のように

フィドルでの私のコードは次のとおりです。ここで私はこれを行う方法を

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

+0

'@ hrishikeshp19':いいえ、私はあなたがしたとは思わなかった。 :-) –

答えて

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

-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"のためにプライベートなものは無意味です。したがって、Barは決して初期化されません。あなたが使うのはFooオブジェクトだけです。 – riship89

4

はい、必要です。あなたの例では、インスタンス化された生徒の数にかかわらず、すべての生徒は同じ性別を持ち、インスタンス化される人は1人だけになります。より良い

は次のようになります。

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'が呼び出されるとすぐにそれを取得します。 –

関連する問題