淺析JS中NEW的實(shí)現(xiàn)原理及重寫
提到new,肯定會(huì)和類和實(shí)例聯(lián)系起來(lái),如:
function Func() {
let x = 100;
this.num = x +
}
let f = new Func();
上面的代碼,我們首先創(chuàng)建了一個(gè)函數(shù),如果是用面向?qū)ο蟮恼f(shuō)法就是創(chuàng)建了一個(gè)Function類的實(shí)例,如果直接執(zhí)行這個(gè)函數(shù),那它就是一個(gè)普通的函數(shù),如果用new執(zhí)行,則這個(gè)函數(shù)被稱為一個(gè)自定義的類。
如果是一個(gè)普通函數(shù)執(zhí)行,他會(huì)如下做幾件事:
·形成一個(gè)全新的執(zhí)行上下文EC(Execution Context 執(zhí)行環(huán)境)
·形成一個(gè)AO(Activation Object 活動(dòng)對(duì)象)變量對(duì)象,初始化arguments和形參賦值
·初始化作用域鏈
·代碼執(zhí)行
如果是new函數(shù)執(zhí)行,它既有普通函數(shù)執(zhí)行的一面,也有自己獨(dú)有的東西:
·默認(rèn)創(chuàng)建一個(gè)對(duì)象,而這個(gè)對(duì)象就是當(dāng)前類的實(shí)例
·聲明其this指向,讓其指向這個(gè)新創(chuàng)建的實(shí)例
·不論其是否寫return,都會(huì)把新創(chuàng)建的實(shí)例返回,這里有個(gè)特殊點(diǎn),如果用戶自己返回內(nèi)容,且返回的是一個(gè)引用類型值,則會(huì)把默認(rèn)返回的實(shí)例給覆蓋掉,此時(shí)返回的值就不再是類的實(shí)例了
console.log(f); //=>{num:200}
//f是Func這個(gè)類的實(shí)例
//相當(dāng)于給創(chuàng)建的實(shí)例對(duì)象新增一個(gè)num的屬性 obj.num=200 (因?yàn)榫邆淦胀ê瘮?shù)執(zhí)行的一面,所以只有this.xxx=xxx才和創(chuàng)建的實(shí)例有關(guān)系,此案例中的x只是AO中的私有變量)
console.log(f instanceof Func); //=>TRUE instanceof用來(lái)檢測(cè)某一個(gè)實(shí)例是否屬于這個(gè)類
每一次new出來(lái)的都是一個(gè)新的實(shí)例對(duì)象
console.log(f === f2); //=>false
既然知道了new都做了什么事情,我們重新一下new:
/*
* 內(nèi)置NEW的實(shí)現(xiàn)原理
* @params
* Func:操作的那個(gè)類
* ARGS:NEW類的時(shí)候傳遞的實(shí)參集合
* @return
* 實(shí)例或者自己返回的對(duì)象
*/
function _new(Func, ...args) {
//默認(rèn)創(chuàng)建一個(gè)實(shí)例對(duì)象(而且是屬于當(dāng)前這個(gè)類的一個(gè)實(shí)例)
let obj = {};
//也會(huì)把類當(dāng)做普通函數(shù)執(zhí)行
//執(zhí)行的時(shí)候要保證函數(shù)中的this指向創(chuàng)建的實(shí)例
let result = Func.call(obj, ...args);
//若客戶自己返回引用值,則以自己返回的為主,否則返回創(chuàng)建的實(shí)例
if ((result !== null && typeof result === "object") || (typeof result === "function")) {
return result;
}
return obj;
}
我們?cè)囈幌拢?/p>
let f3 = _new(Func);
console.log(f3); // =>{num: 200}
我們繼續(xù)測(cè)試:
Func.prototype.log = function () {
console.log('ok');
}
let f4 = _new(Func);
f4.log(); //=>Uncaught TypeError: f4.log is not a function
也就是說(shuō),F(xiàn)unc原型上的方法其實(shí)例沒(méi)法調(diào)用,我們還需要修改:
/*
* 內(nèi)置NEW的實(shí)現(xiàn)原理
* @params
* Func:操作的那個(gè)類
* ARGS:NEW類的時(shí)候傳遞的實(shí)參集合
* @return
* 實(shí)例或者自己返回的對(duì)象
*/
function _new(Func, ...args) {
//默認(rèn)創(chuàng)建一個(gè)實(shí)例對(duì)象(而且是屬于當(dāng)前這個(gè)類的一個(gè)實(shí)例)
// let obj = {};
let obj = Object.create(Func.prototype);
//也會(huì)把類當(dāng)做普通函數(shù)執(zhí)行
//執(zhí)行的時(shí)候要保證函數(shù)中的this指向創(chuàng)建的實(shí)例
let result = Func.call(obj, ...args);
//若客戶自己返回引用值,則以自己返回的為主,否則返回創(chuàng)建的實(shí)例
if ((result !== null && typeof result === "object") || (typeof result === "function")) {
return result;
}
return obj;
}
這樣應(yīng)該就可以了。
let f6 = _new(Func); f6.log(); //=>ok
總結(jié)
以上所述是小編給大家介紹的JS中NEW的實(shí)現(xiàn)原理及重寫,希望對(duì)大家有所幫助,也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
bootstrap modal+gridview實(shí)現(xiàn)彈出框效果
這篇文章主要介紹了bootstrap modal+gridview實(shí)現(xiàn)彈出框效果,gridview點(diǎn)擊更新彈出填寫信息表單,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
webpack 插件html-webpack-plugin的具體使用
本篇文章主要介紹了webpack 插件html-webpack-plugin的具體使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-04
JavaScript實(shí)現(xiàn)一個(gè)電子小蜘蛛
這篇文章主要介紹了JavaScript實(shí)現(xiàn)一個(gè)電子小蜘蛛,具體的樣子就是讓它會(huì)跟隨著我們的鼠標(biāo)進(jìn)行移動(dòng),那么我們?nèi)绾螌?shí)現(xiàn)這樣的效果呢,下面來(lái)詳細(xì)講解實(shí)現(xiàn)方法,需要的朋友可以參考下2024-10-10
js生成的驗(yàn)證碼的實(shí)現(xiàn)與技術(shù)分析
本文主要是分享了一段由JS生成驗(yàn)證碼并驗(yàn)證的代碼,非常簡(jiǎn)單,并分析了此方法的實(shí)用性,提供給大家參考下2014-09-09
純js實(shí)現(xiàn)動(dòng)態(tài)時(shí)間顯示
這篇文章主要為大家詳細(xì)介紹了純js實(shí)現(xiàn)動(dòng)態(tài)時(shí)間顯示,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
layui之select的option疊加問(wèn)題的解決方法
下面小編就為大家分享一篇layui之select的option疊加問(wèn)題的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03
微信小程序 調(diào)用遠(yuǎn)程接口 給全局?jǐn)?shù)組賦值代碼實(shí)例
這篇文章主要介紹了微信小程序 調(diào)用遠(yuǎn)程接口 給全局?jǐn)?shù)組賦值代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08
JavaScript必知必會(huì)(二) null 和undefined
這篇文章主要介紹了JavaScript必知必會(huì)(二) null 和undefined的相關(guān)資料,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06
js指定步長(zhǎng)實(shí)現(xiàn)單方向勻速運(yùn)動(dòng)
這篇文章主要為大家詳細(xì)介紹了js指定步長(zhǎng)實(shí)現(xiàn)單方向勻速運(yùn)動(dòng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07

