js的繼承方法小結(jié)(prototype、call、apply)(推薦)
js的原型繼承 -- prototype
先說(shuō)下什么是prorotype?
- js中,俗話說(shuō)“一切皆對(duì)象”。用new 出來(lái)的都是函數(shù)對(duì)象;否則就是普通對(duì)象
- 函數(shù)對(duì)象都有prototype(原型對(duì)象);而普通對(duì)象則只有__proto__(原型指針)
- 函數(shù)對(duì)象的一個(gè)特點(diǎn):可以實(shí)現(xiàn)不同類(lèi)之間的方法繼承
- 函數(shù)的子類(lèi)可以共享父類(lèi)的方法,而父類(lèi)不能想用子類(lèi)的方法
eg: (prototype的繼承)
//創(chuàng)建父類(lèi)函數(shù)對(duì)象
function Personal(name, age) {
this.name = name; //父類(lèi)的私有屬性
this.age = age;
this.house = ['北京', '上海']
}
Personal.prototype.run = function() { //給父類(lèi)原型動(dòng)態(tài)添加方法
alert('原型方法:' + this.name + ' is running!');
}
var per = new Personal('小白', 24)
per.run() //打印 --> 原型方法:小白 is running!
//創(chuàng)建子類(lèi)函數(shù)對(duì)象
function Boy() {}
Boy.prototype = new Personal('小黑', 19) //子類(lèi)繼承父類(lèi)的所有屬性和方法
Boy.prototype.source = 100 //給子類(lèi)添加原型屬性
Boy.prototype.printSource = function() { //給子類(lèi)添加方法
alert(this.name + '的原型方法printSouce打印成績(jī)?yōu)椋? + this.source) //小黑的原型方法printSouce打印成績(jī)?yōu)椋?00
}
Boy.prototype.run() //打印 --> 原型方法:小黑 is running!
var boys = new Boy()
boys.printSource()
console.log(boys, '--boys---') //打印 -->19, 小黑, 100 (這里會(huì)沿著prototype向上查找到Personal的屬性)
以下是關(guān)于prototype繼承需要注意的點(diǎn):
1.如果父類(lèi)中有引用類(lèi)型的屬性:Array,Object等。子類(lèi)繼承了這些屬性,并嘗試改變的話,會(huì)影響到父類(lèi)的屬性。
//創(chuàng)建另外一個(gè)實(shí)例1:
var boys1 = new Boy()
boys1.house.push('深圳')
//打印這兩個(gè)實(shí)例:
console.log(boys, boys1)

可以看出來(lái),當(dāng)屬性為引用類(lèi)型時(shí),只要有一個(gè)實(shí)例的屬性做了操作,所有的實(shí)例都會(huì)受到影響。
2.該方式導(dǎo)致 Boy.prototype.constructor 被重寫(xiě),它指向的是 Personal 而非 Boy。因此你需要手動(dòng)將 Boy.prototype.constructor 指回 Boy。
Boy.prototype = new Personal(); Boy.prototype.constructor === Personal; // true // 重寫(xiě) Boy.prototype 中的 constructor 屬性,指向自己的構(gòu)造函數(shù) Boy Boy.prototype.constructor = Boy;
3.因?yàn)?Boy.prototype = new Personal(); 重寫(xiě)了 Boy 的原型對(duì)象,所以 printSource 放在重寫(xiě)原型對(duì)象之前會(huì)被覆蓋掉,因此給子類(lèi)添加原型方法必須在替換原型之后(eg是沒(méi)有被覆蓋的)。
function Boy() {}
Boy.prototype = new Personal();
// 給子類(lèi)添加原型方法必須在替換原型之后
Boy.prototype.printSource = function() {
console.log('printSource~');
};
4.創(chuàng)建 boys 實(shí)例時(shí)無(wú)法向父類(lèi)的構(gòu)造函數(shù)傳參,也就是無(wú)法初始化 source屬性。因此:只能創(chuàng)建實(shí)例之后再修改父類(lèi)的屬性。
const boys = new Boy(); // 只能創(chuàng)建實(shí)例之后再修改父類(lèi)的屬性 boys.source = 100;
apply()、call()方法的繼承
了解下apply()、call()方法
1.apply()、call()的用法:
obj.call(thisObj, arg1, arg2, ...); obj.apply(thisObj, [arg1, arg2, ...]);
obj是父級(jí),thisObj是子級(jí);第二個(gè)參數(shù)apply可以接收一個(gè)數(shù)組,而call只能是每項(xiàng)逐個(gè)接收。
2.apply和call 本來(lái)就是為了擴(kuò)展函數(shù)的作用域而生的,換句話說(shuō)就是為了改變this的指向存在的。
3.當(dāng)一個(gè)object沒(méi)有某種方法,但是其他的有,我們可以借助call和apply來(lái)用其他對(duì)象的方法來(lái)做操作,也可以傳參數(shù)。
//eg:
function Personal(name, sex) {
this.name = name;
this.sex = sex;
this.say = function (){
alert('姓名:' + this.name + ';性別:' + this.sex)
}
}
const per = new Personal('Allan', '男')
per.say();
//apply()方法實(shí)現(xiàn):
function Girls(name, sex) {
Personal.apply(this, [name, sex]);
//Person.apply(this,arguments); //跟上句一樣的效果,arguments
//Print.apply(this,arguments); //還可以實(shí)現(xiàn)繼承多個(gè)父類(lèi),但是原型 prototype只能繼承一個(gè)父類(lèi)!??!切記
}
const girls1 = new Girls('Lucy', '女')
girls1.say();
//call()實(shí)現(xiàn):
function Boy(name, sex) {
Personal.call(this, name, sex);
}
const boys = new Boy('Barry', '男');
boys.say() //
總結(jié):
- prototype可以動(dòng)態(tài)的給對(duì)象增加屬性和方法。
- 可以實(shí)現(xiàn)子類(lèi)繼承父類(lèi),擁有父類(lèi)的屬性和方法。
- call和apply的區(qū)別,在于參數(shù)的不同。
- call和apply,理解為在子類(lèi)的運(yùn)行環(huán)境中執(zhí)行父類(lèi)的方法和屬性。
- call和apply可以實(shí)現(xiàn)一個(gè)子類(lèi)繼承多個(gè)父類(lèi),但是prototype只能有一個(gè)父類(lèi)。
以上所述是小編給大家介紹的js的繼承方法小結(jié)詳解整合,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
JS實(shí)現(xiàn)JSON.stringify的實(shí)例代碼講解
JSON.stringify是瀏覽器高版本帶的一個(gè)將JS的Objtect對(duì)象轉(zhuǎn)換為JSON字符串的一個(gè)方法,不過(guò)再I(mǎi)E6下面,并不存在JSON這一對(duì)象,因此,用到此方法時(shí),需要寫(xiě)一套兼容性的代碼。接下來(lái)通過(guò)本文給大家分享JS實(shí)現(xiàn)JSON.stringify的實(shí)例代碼,需要的朋友參考下吧2017-02-02
JavaScript通過(guò)function定義對(duì)象并給對(duì)象添加toString()方法實(shí)例分析
這篇文章主要介紹了JavaScript通過(guò)function定義對(duì)象并給對(duì)象添加toString()方法,實(shí)例分析了javascript中function定義對(duì)象及添加方法的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03
js實(shí)現(xiàn)的點(diǎn)擊數(shù)量加一可操作數(shù)據(jù)庫(kù)
這篇文章主要介紹了js如何實(shí)現(xiàn)的點(diǎn)擊數(shù)量加一操作數(shù)據(jù)庫(kù),需要的朋友可以參考下2014-05-05
詳解html-webpack-plugin插件(用法總結(jié))
這篇文章主要介紹了詳解html-webpack-plugin插件(用法總結(jié)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09
關(guān)于include標(biāo)簽導(dǎo)致js路徑找不到的問(wèn)題分析及解決
本文為大家詳細(xì)介紹下關(guān)于使用jsp:include標(biāo)簽及<%@ include標(biāo)簽時(shí)要注意的事項(xiàng)以及實(shí)測(cè)發(fā)現(xiàn)問(wèn)題并解決問(wèn)題的全過(guò)程,感興趣的各位可以參考下哈,希望對(duì)大家有所幫助2013-07-07
使用純JS代碼判斷字符串中有多少漢字的實(shí)現(xiàn)方法(超簡(jiǎn)單實(shí)用)
這篇文章主要給大家介紹了js判斷字符串中有多少漢字的實(shí)現(xiàn)方法然后給大家分享了使用JS判斷輸入字符串長(zhǎng)度的兩種方法,非常不錯(cuò)具有參考借鑒價(jià)值,感興趣的朋友一起看看吧2016-11-11

