一屿笼、實例從構(gòu)造函數(shù)的原型身上繼承方法
原理:
任何一個new出來的實例上都可使用原型對象上的方法鸠项,視為最基礎(chǔ)的繼承婚被。(在原型上創(chuàng)建方法和在函數(shù)內(nèi)創(chuàng)建方法都可以繼承)
function Fn(){
this.name = "admin";
}
// 在原型對象上新建一個方法
Fn.prototype.show = function(){
console.log(this.name);
}
var f = new Fn();
console.log(f); //Fn {name: "admin"}
console.log(f.name); //admin
// 實例調(diào)用這個方法
console.log(f.show); //f(){console.log(tihs.name)}
二、構(gòu)造函數(shù)繼承
原理:
改變this指向洗做,使用bind(),call(),apply()改變this指向
優(yōu)缺點:
只能繼承構(gòu)造函數(shù)中的屬性和方法弓叛,不能繼承原型上的屬性和方法
簡單方便,創(chuàng)建子類實例時诚纸,可以向父類的構(gòu)造器傳參撰筷;
可以實現(xiàn)多繼承,可以繼承多個構(gòu)造函數(shù)中的內(nèi)容
// 改變this指向畦徘,繼承構(gòu)造函數(shù)中的屬性
function Parent(n,a){
this.name = n;
this.age = a;
}
function Child(n,a){
// 在子構(gòu)造函數(shù)中調(diào)用父構(gòu)造函數(shù)
Parent.call(this,n,a); //改變this的指向為child,復制成一個新對象
}
var p = new Parent("大明",48);
var c = new Child("小明",18);
console.log(p);
console.log(c);
三毕籽、原型對象繼承
原理:
通過原型對象prototype來實現(xiàn)繼承
優(yōu)缺點:
- 可以繼承原型的方法和屬性,不能繼承構(gòu)造函數(shù)的方法和屬性
function Parent(n){
this.name = n;
}
Parent.prototype.show = function(){
console.log(this.name);
}
// 淺拷貝
// Child.prototype = Parent.prototype;
// 深拷貝
for(var i in Parent.prototype){
Child.prototype[i] = Parent.prototype[i];
}
function Child(n){
this.name = n;
}
Child.prototype.show = function(){
console.log("hello");
}
var p = new Parent("小頭爸爸");
var c = new Child("大頭兒子");
// console.log(Parent.prototype); //{show: ?, constructor: ?}
p.show();
c.show();
console.log(p);
console.log(c);
// 淺拷貝
// Child.prototype = Parent.prototype;
只是改變了地址井辆,子函數(shù)的constructor指向了父函數(shù)的constructor关筒,如果修改子函數(shù)的原型對象的方法,會同時改變父函數(shù)的
// 深拷貝
for(var i in Parent.prototype){
Child.prototype[i] = Parent.prototype[i];
}
地址和值都改變杯缺,子函數(shù)的constructor指向不變
四蒸播、原型鏈繼承
原理:
Child的原型對象指向Parent實例化的對象,Child的實例萍肆,可以訪問Parent構(gòu)造函數(shù)內(nèi)部的this的屬性和原型上的方法
優(yōu)缺點:
既可以繼承構(gòu)造函數(shù)中的方法和屬性袍榆,又可以繼承原型上的方法和屬性
不方便傳參
原型上的屬性是共享的,一個實例修改了原型屬性塘揣,另一個實例的原型屬性也會被修改
function Parent(n,a){
this.name = n;
this.age = a;
this.hi = "hello";
}
Parent.prototype.show = function(){
console.log(this.name);
}
function Child(n,a,s){
Parent.call(this,n,a);
this.score = s;
}
// Child的原型對象指向Parent實例化的對象
Child.prototype = new Parent();
//子的原型對象的constructor被改變包雀,所以需要手動指回
Child.prototype.constructor = Child;
Child.prototype.school = function(){
console.log("go school");
}
var p = new Parent("大明",48);
var c = new Child("小明",18,100);
console.log(p);
console.log(c);
console.log(hi);
// Child的原型對象指向Parent實例化的對象
Child.prototype = new Parent();
//子的原型對象的constructor被改變,所以需要手動指回
Child.prototype.constructor = Child;
五勿负、混合繼承
原理:
改變this指向繼承+原型對象繼承
優(yōu)缺點:
- 既能繼承構(gòu)造函數(shù)中的屬性馏艾,又能繼承構(gòu)造函數(shù)的prototype上的方法
function Parent(n){
this.name = n;
}
Parent.prototype.show = function(){
console.log(this.name);
}
function Child(n){
// 改變this指向改變構(gòu)造函數(shù)上的屬性
Parent.call(this,n);
}
// 原型對象繼承(深拷貝)原型上的方法
for(var i in Parent.prototype){
Child.prototype[i] = Parent.prototype[i];
}
// 檢測是改變子構(gòu)造函數(shù)的方法是否影響父構(gòu)造函數(shù)的方法
// Child.prototype.show = function(){
// console.log("hello");
// }
var p = new Parent("小明");
var c = new Child("小紅");
p.show();
c.show();
六、ES6的class類繼承:
原理:
構(gòu)造函數(shù)繼承(改變this指向)+原型鏈繼承
優(yōu)缺點:
- 既能繼承屬性又能繼承方法
關(guān)鍵字extends:子類可以通過extends繼承父類里面的屬性和方法奴愉;
super關(guān)鍵字:用于訪問和調(diào)用父類上的函數(shù)琅摩;
? ? ? ? 可以調(diào)用父類里面的構(gòu)造函數(shù),也可以調(diào)用父類里面的普通函數(shù)方法锭硼;
class Parent {
constructor(n){
this.name = n;
}
show(){
console.log(this.name);
}
}
class Child extends Parent { //繼承Parent的屬性和方法
constructor(n){
super(n); //調(diào)用Parent房资,并傳參
}
// show(){
// console.log("hello");
// }
}
var p = new Parent("小頭爸爸");
var c = new Child("大頭兒子");
p.show();
c.show();
console.log(p);
console.log(c);
補充相關(guān)知識點:
構(gòu)造函數(shù)
- 主要用來初始化對象,即為對象成員變量賦初始值檀头,和new一起使用轰异。把對象中一些公共的屬性和方法抽取出來岖沛,然后封裝到這個函數(shù)里面。
new的作用
- 內(nèi)存中創(chuàng)建一個新的空對象搭独;
- 讓this指向這個新對象婴削;
- 執(zhí)行構(gòu)造函數(shù)里面的代碼,給這個新對象添加屬性和方法牙肝;
- 檢查原函數(shù)里有沒有主動返回對象唉俗,沒有就返回新對象(所以構(gòu)造函數(shù)里不需要return)。
原型對象prototype:
- 每個函數(shù)都有一個prototype屬性配椭,指向另外一個對象虫溜。這個prototype就是一個對象,這個對象的所有屬性和方法股缸,都會被構(gòu)造函數(shù)所擁有衡楞。
- 可以把不變的方法,直接定義在prototype對象上敦姻,所有對象的實例就可以共享這個方法瘾境。
- 一般情況下,我們的公共屬性定義到構(gòu)造函數(shù)里面镰惦,公共的方法放到原型對象身上寄雀。
對象原型proto:
對象實例里面都會有一個屬性proto指向構(gòu)造函數(shù)的prototype原型對象。
對象原型意義:為對象的查找機制提供一個方向陨献,但是它是一個非標準屬性盒犹,因此在實際開發(fā)中,一般不直接使用眨业,它只能是內(nèi)部指向原型對象prototype
個人學習總結(jié)分享急膀,若有不當之處,歡迎留言交流~~