所謂繼承,就是子類繼承父類中的屬性和方法, 方案一:原型繼承 方法:子類的原型指向父類的一個實體,
function A() { this.x = 100; } A.prototype.getX = function getX() { console.log(this.x); }; function B() { this.y = 200; } B.prototype.sum=function(){} B.prototype = new A; //B子類 => A父類,讓子類B的原型指向父類A的實體
B.prototype.getY = function getY() { console.log(this.y); }; let b = new B;

通過B.prototype = new A這一句話達成繼承,
js中的面向物件的機制都是基于原型鏈完成的,所以js中的繼承也可以是基于原型鏈的,但這其中又有很多弊端,
比如B之前的原型B.prototype上的方法b已經查找不到,b的constructor應該是B,但現在是A,b可以通過b.__proto__或b.__proto__.__proto__肆意修改父類上的屬性和方法,而父類上不管私有還是公有的屬性和方法都會成為子類公有的,這些種種問題都是需要注意的,這大概就是IE瀏覽器禁止使用__proto__的原因吧,
方案二:call繼承 方法:把父類當做普通函式執行,讓其執行的時候,方法中的this變為子類的實體即可,
function A() { this.x = 100; } A.prototype.getX = function getX() { console.log(this.x); }; function B() { //call繼承 A.call(this); //=>this.x = 100; => b.x=100; this.y = 200; } B.prototype.getY = function getY() { console.log(this.y); }; let b = new B;

call繼承只能繼承父類中的私有屬性(繼承的私有屬性賦值給子類實體的私有屬性),而且是類似拷貝過來一份,不是鏈式查找;因為只是把父類當做普通的方法執行,所以父類原型上的公有屬性方法無法被繼承過來, 方案三:寄生組合繼承 方法:call繼承+變異版的原型繼承共同完成的,
function A() { this.x = 100; } A.prototype.getX = function getX() { console.log(this.x); }; function B() { A.call(this); this.y = 200; } //=>Object.create(OBJ) 創建一個空物件,讓其__proto__指向OBJ(把OBJ作為空物件的原型) B.prototype = Object.create(A.prototype); B.prototype.constructor = B; //把constructor補上 B.prototype.getY = function getY() { console.log(this.y); }; let b = new B; console.log(b);

這個方案利用了call繼承實作私有到私有,利用原型繼承實作了公有到公有,當然還是原型繼承的一些弊端應該注意, 方案四:ES6中class類
class A { constructor() { this.x = 100; } getX() { console.log(this.x); } } //=>extends繼承和寄生組合繼承基本類似 class B extends A { constructor() { super(); //=>一但使用extends實作繼承,只要自己寫了constructor,就必須寫super this.y = 200; } getY() { console.log(this.y); } } let b = new B;

其實extends繼承和寄生組合繼承基本類似,而且必須加上super()函式,它相當于A.call(this), 專案中我們會用到繼承地方比如自己寫插件或者類別庫的時候,還有就是react中用class實作繼承,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/145146.html
標籤:JavaScript
