2013-10-04 136 views
2

考慮讓 的JavaScript繼承的屬性默認值

function Employee() { 
    this.id = ""; 
    this.name = ""; 
    this.gender = ""; 
} 

function Programmer() { 
    this.expertise = ""; 
} 

Programmer.prototype = new Employee(); 

,然後在下面的代碼

我想進一步繼承程序員JScriptProgrammer設置爲「JavaScript的」的「專業知識」默認值。

問題: 什麼是

function JScriptProgrammer() { 
    this.expertise = "JavaScript"; 
} 

JScriptProgrammer.prototype = new Programmer(); 

function JScriptProgrammer() { 
} 

JScriptProgrammer.prototype = new Programmer(); 
JScriptProgrammer.prototype.expertise = "JavaScript"; 
+0

這與原型上的定義屬性與每個實例上定義的屬性之間的區別是相同的。重複[在Javascript中使用'prototype'與'this'?](http://stackoverflow.com/questions/310870/use-of-prototype-vs-this-in-javascript)是否使用'new原型或非原型的程序員實例(一個普通對象)沒有任何區別。 – Bergi

+0

另外,[不要使用'new'繼承](http://stackoverflow.com/questions/12592913/what-is-the-reason-to-use-the-new-keyword-here)。 – Bergi

回答

1

您可以將原型用於對象的默認值,並且可以節省內存。如果你以後不確定地映射屬性(在實例上爲它指定一個新的值),那麼所有實例都會共享同一個指向該值的指針。

然而,如果你必定將值分配給它,然後更好地在構造函數體將其定義爲this.myval

這裏是指定的默認值,以原型的棘手的部分;你必須重新分配一個新的值來實現特定的實例變化。對象值可以通過調用它們上的函數或重新分配屬性來操作。當你這樣做,那麼對於所有實例的默認值改爲:

var Person=function(){}; 
Person.prototype.teeth=[0,1,2,3]; 
Person.prototype.legs={left:1,right:1}; 

var ben=new Person(); 
var betty=new Person(); 
ben.teeth.splice(2,1);//ben looses a tooth 
//when ben looses a tooth like that betty looses it too 
console.log(betty.teeth);//[1,2,3] poor betty 
//now poor betty has an accident 
betty.legs.right=0; 
//looks like ben looses it too 
console.log(ben.legs);//{left:1,right:0} 
//I don't feel sorry for ben though because 
//he knocked out betty's tooth 

最好不要啓動了繼承,您可以使用的Object.create或輔助函數來設置繼承一個新的實例,無需創建一個實例。所有關於繼承,原型,覆蓋和調用超級在這裏:https://stackoverflow.com/a/16063711/1641941

+0

太棒了!因此,使用prototype來爲屬性定義默認值是不好的,因爲它將成爲所有對象實例的共享成員。謝謝!!真的很感謝答案! :) – ch0eb1t

+0

@ ch0eb1t不客氣。在谷歌封閉庫中,原型上定義了所有原始值。所以字符串,數字和布爾值都很好。對象可以使用,但你永遠不能操縱它們,總是重新分配來改變它的值。當你的代碼被其他程序員共享時,他們可能不知道這一點,並得到意想不到的結果,因此對於需要特定於實例的對象成員,我不會在原型上指定它們。 – HMR

-1

之間的性差異在摘要:

原型是使用繼承現有的對象。例如。如果您要添加到數組對象的新方法,你可以做到這一點

Array.prototype.MyNewMethod = function() 
{ 
alert("im bellow to array object") 
} 

這意味着你可以到這個

var array = [1,2,3]; 
array.MyNewMethod();//prints im bellow to array object 

read this post for more reference

這意味着你的代碼做什麼這個:

 function JScriptProgrammer() { 
     } 
     function Programmer(){ 
     this.name = "hello world"; 
     } 
     JScriptProgrammer.prototype = new Programmer();// inhering from Programmers object(or lets say class) 
     JScriptProgrammer.prototype.expertise = "JavaScript"; // assigning a value to expertise property that belows to JScriptProgrammer class 



console.log(new JScriptProgrammer())//JScriptProgrammer {name: "hello world", expertise: "JavaScript"} notice that property name that bellow to Programmer 
object now is in JScriptProgrammer object as well. 

這裏測試http://jsbin.com/IgOFimi/1/edit

+0

我不知道這應該是什麼回答,但代碼並沒有真正展示任何東西。 – Nicole

+0

@Misters:我很抱歉,但我要求的是分配對象的默認值的差異。使用this.expertise和prototype.expertise可以很好地完成這項工作。我只想知道這兩者之間的區別。顯然,必須有一種情況,即更優選使用這種情況,或者當使用原型時更優選。 – ch0eb1t

0

區別

function JScriptProgrammer() { 
this.expertise = "JavaScript"; 
} 
JScriptProgrammer.prototype = new Programmer(); 

當您使用JScriptProgrammer()的專業知識價值已經被設定手段 「的JavaScript」

但是當你用

function JScriptProgrammer() 
{ 
} 
JScriptProgrammer.prototype = new Programmer(); 
JScriptProgrammer.prototype.expertise = "JavaScript"; 

意味着你設定使用JScriptProgrammer後的專業知識價值()

+0

我不認爲這是一個有效的答案。請參閱http://jsbin.com/OQEBaHu/1/編輯日誌輸出「JavaScript」而不是「不JavaScript」。如果使用原型將在construtor調用後稍後設置該值,則示例中的日誌輸出必須是「不是JavaScript」而不是「JavaScript」 – ch0eb1t

0

他們是相同。第二個版本保存內存,這意味着所有的孩子都使用同一個函數/變量實例。

見下例子說明了爲什麼this可能需要

function JScriptProgrammer() { 
    var tmp = "Hello"; 

    //accessing private variables 
    this.sayHello = function() { 
     alert(tmp + " "+ this.expertise + "er"); 
    } 
} 

JScriptProgrammer.prototype = new Programmer(); 
JScriptProgrammer.prototype.expertise = "JavaScript"; 

更多閱讀