物件導向中,繼承相對是比較難的,即使看了很多文章,可能依然不明白,下面我談談我的理解。 1.
建構函式繼承
function p0()
function children0()
通過這種在子類中執行父類的構造函式呼叫,把父類建構函式的
this
指向為子類例項化物件引用,從而導致父類執行的時候父類裡面的屬性都會被掛載到子類的例項上去。
new children0().name; // p0
new children0().colors; // ["pink","black","gray"]
這種方式,父類原型上的東西沒法繼承,因此函式復用也就無從談起
p0.prototype.*** = "男
"; p0.prototype.say = function()
new children0().***; // undefined
// uncaught typeerror: (intermediate value).say is not a function
new children0().say();
缺點:
children0
無法繼承 p0
的原型物件,只能算是部分繼承 2.
原型鏈式繼承
function p1()function children1()
children1.prototype = new p1();
p1.prototype.*** = "女
"; p1.prototype.say = function()
new children1().***; // 女
new children1().say(); //hellow!
這種方式確實解決了上面借用建構函式繼承方式的缺點。
但是,這種方式仍有缺點,如下:
var s1 = new children1();
s1.colors.push("black");
var s2 = new children1();
s1.colors; // (4) ["red", "blue", "yellow", "balck"]
s2.colors; // (4) ["red", "blue", "yellow", "balck"]
在這裡例項化了兩個
children1 ,
s1 中為父類的
colors 屬性
push
了乙個顏色
black
,但是 s2
也改變了。因為原型物件是共用的。
但我們並不想這樣,這是這個方法缺點。 3.
組合式繼承
意思就是把建構函式和原型鏈繼承結合起來。
function p2()
function children2()
children2.prototype = new p2()
var s1 = new children2();
s1.colors.push("black");
var s2 = new children2();
s1.colors; // (4) ["red", "blue", "yellow", "balck"]
s2.colors; // (3) ["red", "blue", "yellow"]
可以看到, s2
和 s1
兩個例項物件已經被隔離了。
但這種方式仍有缺點。父類的建構函式被執行了兩次,第一次是
children2.prototype = new p2()
,第二次是在例項化的時候,這是沒有必要的。
組合式繼承優化 1
直接把父類的原型物件賦給子類的原型物件
function p3()
p3.prototype.*** = "男
"; p3.prototype.say = function()
function children3()
children3.prototype = p3.prototype;
var s1 = new children3();
var s2 = new children3();
console.log(s1, s2);
但是,看如下**:
console.log(s1 instanceof child3); // true
console.log(s1 instanceof parent3); // true
可以看到,我們無法區分例項物件 s1
到底是由
children3
直接例項化的還是 p3
直接例項化的。用
instanceof
關鍵字來判斷是否是某個物件的例項就基本無效了。
我們還可以用
.constructor
來觀察物件是不是某個類的例項:
console.log(s1.constructor.name); // p3
可以看出, s1
的建構函式是父類,而不是子類
children3
,這並不是我們想要的。
組合式繼承優化 2
function p4()
p4.prototype.*** = "男
"; p4.prototype.say = function()
function children4()
children4.prototype=object.create(p4.prototyp;
children4.prototype.constructor = children4;
object.create
是一種建立物件的方式,它會建立乙個中間物件
var p =
var obj = object.create(p)
// object.create()
通過這種方式建立物件,新建立的物件obj的原型就是p,同時obj也擁有了屬性name,這個新建立的中間物件的原型物件就是它的引數。
這種方式解決了上面的所有問題,是繼承的最好實現方式。
JS物件導向 繼承
參考博文 一 物件導向的繼承 1 解析 在原有物件的基礎上,略作修改,得到乙個新的物件,並且不影響原有物件的功能 2 如何新增繼承 拷貝繼承 屬性 call 方法 for in 繼承 子類不影響父類,子類可以繼承父類的一些功能 復用 屬性的繼承 呼叫父類的構造1函式 call 方法的繼承 for i...
js 物件導向 繼承
繼承 將方法的定義放在建構函式中,每建立乙個新物件,都會重複建立該方法一模一樣的副本,浪費記憶體。解決 如果多個子物件都要使用乙個相同的方法時,應該把這個方法放在一種原型物件中,建構函式中不再包含方法定義。原型物件 乙個型別中,專門為所有子物件集中儲存共有方法的物件。同一型別下多個子物件需要用乙個共...
JS 物件導向 繼承
實現繼承是 ecmascript 唯一支援的繼承方式,而這主要是通過原型鏈實現的建構函式 原型和例項的關係 每個建構函式都有乙個原型物件,原型有乙個屬性 constructor 指回建構函式,而例項有乙個內部指標 prototype 指向原型。建構函式 function father console...