2013-03-28 36 views
1

這裏是我的代碼,B類繼承A類:JavaScript類成員在子類中未定義

function A() { 
    this.msg = 'meuahah'; 
    A.prototype.foo = function() { 
     alert(this.msg); 
    } 
} 

function B() { 
    A.call(this); 
    B.prototype.bar = function() { 
     A.prototype.foo(); 
    } 
} 

a = new A(); 
a.foo(); // alerts 'meuahah' 
b = new B(); 
b.bar(); // alerts 'undefined' 

爲什麼不b.bar()顯示 'meuahah'?

+0

哇......我們爲什麼每次調用構造函數時都會在原型中設置東西? – jmar777

+0

當你嘗試alert(a.msg)時它會起作用; – hop

回答

2

你的原型繼承是不完全正確。這可能是更你想要做什麼:

function A() { 
    this.msg = 'meuahah'; 
} 

A.prototype.foo = function() { 
    alert(this.msg); 
} 

function B() { 
    A.call(this); 
} 

B.prototype = new A(); 
B.prototype.bar = function() { 
    this.foo(); 
} 

a = new A(); 
a.foo(); 
b = new B(); 
b.bar(); 

可以在B覆蓋foo這樣的:

B.prototype.foo = function() { 
    // Call the original foo method 
    A.prototype.foo.apply(this, arguments); 
} 
+1

'B.原型= A.prototype'。在設置'B.prototype.bar'後,這是一種危險......現在也有'A.prototype.bar',這可能不是預期的行爲。 – jmar777

+0

好點我想我會暫時停下來;)現在應該修好了。 – Daff

+1

這絕對會更好,但現在的問題是,您將擁有'B.prototype.msg'(以及在'A()'構造函數中設置的任何其他屬性。您最好從'A複製每個屬性。原型'到'B.prototype' – jmar777

2

因爲this勢必會在這種情況下,全局對象。

你調用這個函數

function() { 
     alert(this.msg); 
    } 

,當它沒有被綁定到一個對象。因此this將引用全局對象(在瀏覽器中爲window),並且由於該屬性不具有msg屬性,所以它將提醒未定義。

當你調用a = new A()您創建一個新的對象,加上其原型鏈味精作爲屬性,並設置FOO()。因此,當您撥打a.foo() foo必須與athisa

一般來說,你可能需要看起來更像這樣的東西。

function A() { 
    this.msg = 'meuahah'; 
} 

A.prototype.foo = function() { 
    alert(this.msg); 
} 

function B() { 
    A.call(this); 
} 

B.prototype = Object.create(A.prototype); 

B.prototype.bar = function() { 
    this.foo(); 
} 

你可以閱讀更多有關在javascript如何this作品從this question

0

你只是叫A.prototype.foo功能,所以沒有按msg」不存在。下面是從控制檯輸出,當你console.log(this)A.prototype.foo

A {msg: "meuahah", foo: function} 
A {foo: function} 

第二個就是當你從內B調用它,你可以看到msg不存在。

2

的原因是因爲b.bar顯示器undefined是因爲foo方法的thisprototype,和prototype不具有msg屬性。

你基本錯過了要點,繼承。所以,這裏代碼重訪:

function A() { 
    this.msg = 'meuahah'; 
} 

A.prototype.foo = function() { 
    alert(this.msg); 
} 

function B() { 
    A.call(this); 
} 

// Set the inheritance! Or better, the prototype's chain, 
// so that any instance of B will have methods of A too 
B.prototype = Object.create(A.prototype); 

B.prototype.bar = function() { 
    // Because the inheritance, now B has the A's `foo` method too 
    this.foo(); 
} 

// But... We can also override it. 
B.prototype.foo = function() { 
    // do something 
    alert("override"); 
    // then call the original one 
    A.prototype.foo.call(this); 
} 

希望它有助於對對象和構造函數有一個更好的想法。我也會建議您也調查Object.create,這真的很有幫助;和一般的ES5方法。

讀數Working with Objects它也是一個良好的開端,即使這是一個有點老了。