Javascript實現物件導向繼承
Javacript繼承實現
原型鏈
實現繼承
子類建構函式呼叫時同時呼叫父類建構函式,並將父類建構函式作用域的this指向子類建構函式的this
<script>
//子類建構函式呼叫父類建構函式的繼承實現方法
function Super(){ //父類建構函式
this.val = 1;
this.arr = [1];
}
function Sub(){ //子類建構函式
// 子類公共變數
Super.call(this);//完成繼承,改變作用域指向
}
var sub1 = new Sub(); //子類例項如果想要繼承父類的公共變數,只需要讓構造子類例項時呼叫父類建構函式,並將this指向新物件就可以了
console.log(sub1);
</script>
- 原型鏈繼承
使用父類例項物件充當子類的原型物件屬性
<script>
function Super(){
this.val = 1;
this.arr = [1];
}
function Sub(){
// 子類公共變數
}
Sub.prototype = new Super(); // 核心:拿父類例項來充當子類原型物件
var sub1 = new Sub();
var sub2 = new Sub();
sub1.val = 2;
sub1.arr.push(2);
console.log(sub1.val); // 2,改了
console.log(sub2.val); // 1,沒改,只能改自己的
console.log(sub1.arr); // 1, 2改變了陣列
console.log(sub2.arr); // 1, 2
*問題
(1)繼承到了修改後的 來源是一個物件Object 值型別資料指向同一個陣列物件,一改全改不好用,有侷限性
(2)不能通過子類建構函式例項化修改父類的成員變數—不能向父類例項物件傳參
補充:建構函式例項化傳參
//方便修改
2.借用父類建構函式實現繼承
優化:可以向父類建構函式傳參的問題
不用同一個物件指向
<script>
// 實現向父類建構函式的傳參問題
function Super(val){ //可以傳參
this.val = val;
this.arr = [1];
this.fun = function(){}
}
function Sub(val){
// 用了不同陣列,也實現了同一物件的混淆性
Super.call(this, val); // 核心:借父類的建構函式來增強子類例項(把父類的例項屬性複製了一份給子類例項裝上了)
//this指的是例項化出來的物件
// 子類公共變數
}
var sub1 = new Sub(1);
var sub2 = new Sub(2);
sub1.arr.push(2);
console.log(sub1.val); // 1
console.log(sub2.val); // 2
console.log(sub1.arr); // 1, 2 //子類物件型資料不再公用
console.log(sub2.arr); // 1
alert(sub1.fun === sub2.fun); // false
</script>
存在的問題:
例項方法一對一冗餘
3.組合式繼承
最常用的
把例項函式都放在原型物件上
*考慮相容性的情況下
<script>
// 考慮相容性
function Super(val){ // 只在此處宣告基本屬性和引用屬性
this.val = val;
this.arr = [1];
}
//函式寫在原型物件上
Super.prototype.fun1 = function(){}; // 在此處宣告函式
Super.prototype.fun2 = function(){}; // 把例項函式都放在原型物件上
//其他原型物件上的方法
function Sub(val){
Super.call(this,val); // 核心,保留借用建構函式方式的優點,讓子類繼承父類的基本屬性和引用屬性
// 子類公共變數
}
Sub.prototype = new Super(); // 核心,子類繼承父類函式,實現函式複用
var sub1 = new Sub(1);
var sub2 = new Sub(2);
console.log(sub1.fun1 === sub2.fun1); // true 共用同一個函式
</script>
*宣告函式啥都不發生,僅宣告
子類的屬性:自己的+原型鏈得來的 val,arr,fun1,fun2------查詢時候先找自己的再找原型鏈的
瑕疵:同樣屬性給兩份,浪費了記憶體
4.寄生組合式繼承
*解決記憶體浪費問題
完美但不常用
<script>
function beget(obj){ // 生孩子函式,返回一個將引數物件作為原型物件的函式的例項
var F = function(){};
F.prototype = obj;
return new F();//物件的構造器
}
function Super(){ // 只在此處宣告基本屬性和引用屬性
this.val = val;
this.arr = [1];
}
Super.prototype.fun1 = function(){}; // 在此處宣告函式
function Sub(){
Super.call(this); // 核心,保留借用建構函式方式的優點,讓子類繼承父類的基本屬性和引用屬性
// 獲取父類的成員變數
}
var proto = beget(Super.prototype); // 核心:用beget方法切掉了原型物件上多餘的那份父類例項屬性
proto.constructor = Sub; // 核心:將子類建構函式賦予beget出的物件的constructor屬性
Sub.prototype = proto; // 核心:將beget出的物件賦予子類建構函式的prototype屬性
var sub = new Sub();
console.log(sub.val);
console.log(sub.arr);
</script>
!!! 轉載請註明出處
相關文章
- JavaScript物件導向—繼承的實現JavaScript物件繼承
- Javascript物件導向與繼承JavaScript物件繼承
- 說清楚javascript物件導向、原型、繼承JavaScript物件原型繼承
- JavaScript物件導向 ~ 原型和繼承(1)JavaScript物件原型繼承
- 《JavaScript物件導向精要》之五:繼承JavaScript物件繼承
- JavaScript物件導向那些東西-繼承JavaScript物件繼承
- 物件導向--繼承物件繼承
- 物件導向:繼承物件繼承
- 物件導向-繼承物件繼承
- Golang物件導向_繼承Golang物件繼承
- 物件導向之繼承物件繼承
- java物件導向繼承Java物件繼承
- 物件導向之_繼承概念物件繼承
- JavaScript物件導向之二(建構函式繼承)JavaScript物件函式繼承
- 21. 物件導向之繼承物件繼承
- 物件導向 -- 三大特性之繼承物件繼承
- JAVA物件導向高階一:繼承Java物件繼承
- 5-Java物件導向-繼承(下)Java物件繼承
- java學習——物件導向之繼承Java物件繼承
- golang-gin框架實現物件導向-控制器繼承篇Golang框架物件繼承
- JS物件導向程式設計(四):繼承JS物件程式設計繼承
- JS物件導向:JS繼承方法總結JS物件繼承
- python物件導向的繼承-組合-02Python物件繼承
- java-物件導向程式設計--繼承Java物件程式設計繼承
- go物件導向思想:封裝、繼承、多肽Go物件封裝繼承
- 實現JavaScript繼承JavaScript繼承
- JavaScript之物件繼承JavaScript物件繼承
- JavaScript物件冒充繼承JavaScript物件繼承
- JS的物件導向(理解物件,原型,原型鏈,繼承,類)JS物件原型繼承
- Java物件導向03——三大特性之繼承Java物件繼承
- Java中物件導向三大特性之繼承Java物件繼承
- ~~核心程式設計(五):物件導向——多繼承~~程式設計物件繼承
- Javascript如何實現繼承JavaScript繼承
- Javascript 中實現物件原型繼承的三種方式JavaScript物件原型繼承
- JAVA物件導向基礎--封裝 繼承 多型Java物件封裝繼承多型
- 理解Js中物件導向程式設計的繼承JS物件程式設計繼承
- 物件導向三大特性-----封裝、繼承、多型物件封裝繼承多型
- 「MoreThanJava」Day 5:物件導向進階——繼承詳解Java物件繼承