JavaScript原型鏈和繼承詳解
上一篇 JavaScript作用域和閉包詳細總結
文章目錄
- JavaScript原型鏈和繼承詳解
- 一、原型
- 二、原型鏈
- 原型鏈圖解
- 了解this與call/apply方法
- 三、繼承
一、原型
1.定義:原型是 function 物件的一個屬性,它定義了建構式制造出的物件的公共祖
先,通過該建構式產生的物件,可以繼承該原型的屬性和方法,原型也是物件,
2.利用原型特點和概念,可以提取共有屬性,
3.物件屬性的增刪和原型上屬性增刪改查,
4.物件如何查看原型 ==> 隱式屬性 __ proto __
5.物件如何查看物件的建構式 ==> constructor,
自己身上有屬性,原型上也有屬性,取近的,用自己的
二、原型鏈
1、構成原型鏈
Grand.prototype.lastName = "dzq";
function Grand(){};
var grand = new Grand();//grand物件繼承了祖先的的lastName屬性
console.log(grand.lastName);
Father.prototype = grand;//將物件grand賦給Father的原型
function Father(){
this.name = "lyh";
};
var father = new Father();//father就可以拿到lastName屬性和它自己的name屬性
console.log(father.lastName,father.name);
Son.prototype = father;//同理將物件father賦給Son的原型
function Son(){
this.hehe = "txc";
};
var son = new Son();//son就能拿到lastName、name屬性,和自己的hehe屬性
console.log(son.lastName,son.name,son.hehe)
2、原型鏈上屬性的增刪改查
原型鏈上的增刪改查和原型基本上是一致的,只有本人有的權限,子孫是沒有的,
3、誰呼叫的方法內部 this 就是誰
4、絕大多數物件的最終都會繼承自Object.prototype
5、Object.create(原型);
Object.create 也能創建物件,var obj = Object.create(這里必須要有原型)
6、原型方法上的重寫
原型上有這個方法,我自己又寫了一個和原型上同一名字,但不同功能的方法,叫
做重寫(同一名字的函式,不同重寫方式)
通過回傳值,形參串列不同傳參
同樣的名實作不同功能的,就是重寫
原型鏈圖解

了解this與call/apply方法
this
1.函式預編譯程序 this —>指向 window
2.全域作用域里 this —> 指向 window
3.obj.func(); func()里面的 this 指向 obj(誰呼叫這個函式this就指向誰)
4.call/apply 可以改變函式運行時 this 指向,它們兩的區別,是后面傳的引數形式不同,
call
直接執行 Person.call ( )和 Person ( )沒有區別
Person.call( );括號里面可以傳東西
如果 Person.call( obj );里面的 call 讓 person 所有的 this 都變成 obj
不 new 的話,this 默認指向 window,call 的使用必須要 new
call 的第一位引數用于改變 this 指向,第二位實參(對應第一個形參)及以后的引數都當做正常的實參,傳到形參里面去
function Person(name,age,sex){
this.name=name;
this,age=age;
this.sex=sex;
}
function Student(name,age,sex,tel,grade){
this.name=name;
this.age=age;
this.sex=sex;
this.tel=tel;
this.grade=grade;
}
var student =new Student("sunny","123","male",123,2000)
/*call 改變 this 指向,借用別人的函式,實作自己的功能,
只能在你的需求完全涵蓋別人的時候才能使用
如果不想要 age 這個,就不能使用這種方法*/
function Person(name,age,sex){
this.name=name;
this,age=age;
this.sex=sex;
}
function Student(name,age,sex,tel,grade){
Person.call(this,name,age,sex)
this.tel=tel;
this.grade=grade;
}
/*Person.call(this, name, age, sex);里面的 this 現在是 new 了以后的 var this={}
利用 Person 方法,實作了 Student 自己的封裝*/
apply
apply 也是改變 this 指向的,只是傳參串列不同,第一位也是改變 this 指向的人,第
二位,apply 只能傳一個實參,而且必須傳陣列 argunments
call 需要把實參按照形參的個數傳進去
三、繼承
繼承發展史
1.傳統形式 ==> 原型鏈
問題:過多的繼承了沒用的屬性
2.借用建構式 ==>利用 call、apply 所以不算標準的繼承模式
1)不能繼承借用建構式的原型
2)每次建構式都要多走一個函式 ==>浪費效率
3.共享原型(較好的繼承方法)
不能隨便改動自己的原型
Father.prototype.lastName = 'dzq';
function Father(){};
function Son(){};
Son.prototype = Father.prototype;//原型物件指向一個房間
var son = new Son();
圣杯模式
圣杯模式是在方法三的共有原型,但是在共有原型的基礎上有改變,
共享原型是:son.prototype=father.prototype
圣杯模式是:另外加個建構式 function F(){}當做中間層,然后讓 F 和 father 共
有一個原型 F.prototype=father.prototype,然后 son.prototype = new F();使用原
型鏈形成了繼承關系,現在改 son.prototype 就不會影響 father.prototype
var inherit = (function (){
var F = function(){};//定義一個中間建構式,私有化變數
return function (target,origin){//target接受繼承者,origin繼承的目標
F.prototype = origin.prototype;//將繼承的目標原型物件賦給F.prototype
target.prototype = new F();
//new一個實體物件賦給接受繼承的target
//new后,Target.prototype指向的一個全新的地方
//改變Target的原型鏈就不會影響到Origin
target.prototype.constuctor = target;//將constructor指向自己
target.prototype.uber = origin.prototype;//保存自己真正繼承的目標,以便后期訪問
}
}());
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/300627.html
標籤:其他
下一篇:函式作用域和立即執行函式
