您好,登錄后才能下訂單哦!
這篇文章主要介紹了JS中NEW的實現(xiàn)原理是什么,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
提到new,肯定會和類和實例聯(lián)系起來,如:
function Func() { let x = 100; this.num = x + } let f = new Func();
上面的代碼,我們首先創(chuàng)建了一個函數(shù),如果是用面向?qū)ο蟮恼f法就是創(chuàng)建了一個Function類的實例,如果直接執(zhí)行這個函數(shù),那它就是一個普通的函數(shù),如果用new執(zhí)行,則這個函數(shù)被稱為一個自定義的類。
如果是一個普通函數(shù)執(zhí)行,他會如下做幾件事:
·形成一個全新的執(zhí)行上下文EC(Execution Context 執(zhí)行環(huán)境)
·形成一個AO(Activation Object 活動對象)變量對象,初始化arguments和形參賦值
·初始化作用域鏈
·代碼執(zhí)行
如果是new函數(shù)執(zhí)行,它既有普通函數(shù)執(zhí)行的一面,也有自己獨(dú)有的東西:
·默認(rèn)創(chuàng)建一個對象,而這個對象就是當(dāng)前類的實例
·聲明其this指向,讓其指向這個新創(chuàng)建的實例
·不論其是否寫return,都會把新創(chuàng)建的實例返回,這里有個特殊點(diǎn),如果用戶自己返回內(nèi)容,且返回的是一個引用類型值,則會把默認(rèn)返回的實例給覆蓋掉,此時返回的值就不再是類的實例了
console.log(f); //=>{num:200} //f是Func這個類的實例 //相當(dāng)于給創(chuàng)建的實例對象新增一個num的屬性 obj.num=200 (因為具備普通函數(shù)執(zhí)行的一面,所以只有this.xxx=xxx才和創(chuàng)建的實例有關(guān)系,此案例中的x只是AO中的私有變量) console.log(f instanceof Func); //=>TRUE instanceof用來檢測某一個實例是否屬于這個類
每一次new出來的都是一個新的實例對象
console.log(f === f2); //=>false
既然知道了new都做了什么事情,我們重新一下new:
/* * 內(nèi)置NEW的實現(xiàn)原理 * @params * Func:操作的那個類 * ARGS:NEW類的時候傳遞的實參集合 * @return * 實例或者自己返回的對象 */ function _new(Func, ...args) { //默認(rèn)創(chuàng)建一個實例對象(而且是屬于當(dāng)前這個類的一個實例) let obj = {}; //也會把類當(dāng)做普通函數(shù)執(zhí)行 //執(zhí)行的時候要保證函數(shù)中的this指向創(chuàng)建的實例 let result = Func.call(obj, ...args); //若客戶自己返回引用值,則以自己返回的為主,否則返回創(chuàng)建的實例 if ((result !== null && typeof result === "object") || (typeof result === "function")) { return result; } return obj; }
我們試一下:
let f3 = _new(Func); console.log(f3); // =>{num: 200}
我們繼續(xù)測試:
Func.prototype.log = function () { console.log('ok'); } let f4 = _new(Func); f4.log(); //=>Uncaught TypeError: f4.log is not a function
也就是說,F(xiàn)unc原型上的方法其實例沒法調(diào)用,我們還需要修改:
/* * 內(nèi)置NEW的實現(xiàn)原理 * @params * Func:操作的那個類 * ARGS:NEW類的時候傳遞的實參集合 * @return * 實例或者自己返回的對象 */ function _new(Func, ...args) { //默認(rèn)創(chuàng)建一個實例對象(而且是屬于當(dāng)前這個類的一個實例) // let obj = {}; let obj = Object.create(Func.prototype); //也會把類當(dāng)做普通函數(shù)執(zhí)行 //執(zhí)行的時候要保證函數(shù)中的this指向創(chuàng)建的實例 let result = Func.call(obj, ...args); //若客戶自己返回引用值,則以自己返回的為主,否則返回創(chuàng)建的實例 if ((result !== null && typeof result === "object") || (typeof result === "function")) { return result; } return obj; }
這樣應(yīng)該就可以了。
let f6 = _new(Func); f6.log(); //=>ok
JavaScript是一種直譯式的腳本語言,其解釋器被稱為JavaScript引擎,是瀏覽器的一部分,JavaScript是被廣泛用于客戶端的腳本語言,最早是在HTML網(wǎng)頁上使用,用來給HTML網(wǎng)頁增加動態(tài)功能。
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“JS中NEW的實現(xiàn)原理是什么”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。