欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺析JS中NEW的實(shí)現(xiàn)原理及重寫(xiě)

 更新時(shí)間:2020年02月20日 08:24:46   作者:1800000000nm  
本文通過(guò)實(shí)例代碼給大家介紹了JS中NEW的實(shí)現(xiàn)原理及重寫(xiě),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧

提到new,肯定會(huì)和類(lèi)和實(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類(lèi)的實(shí)例,如果直接執(zhí)行這個(gè)函數(shù),那它就是一個(gè)普通的函數(shù),如果用new執(zhí)行,則這個(gè)函數(shù)被稱(chēng)為一個(gè)自定義的類(lèi)。

如果是一個(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)前類(lèi)的實(shí)例

  ·聲明其this指向,讓其指向這個(gè)新創(chuàng)建的實(shí)例

  ·不論其是否寫(xiě)return,都會(huì)把新創(chuàng)建的實(shí)例返回,這里有個(gè)特殊點(diǎn),如果用戶(hù)自己返回內(nèi)容,且返回的是一個(gè)引用類(lèi)型值,則會(huì)把默認(rèn)返回的實(shí)例給覆蓋掉,此時(shí)返回的值就不再是類(lèi)的實(shí)例了

console.log(f); //=>{num:200}
//f是Func這個(gè)類(lèi)的實(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è)類(lèi)

每一次new出來(lái)的都是一個(gè)新的實(shí)例對(duì)象

console.log(f === f2); //=>false

既然知道了new都做了什么事情,我們重新一下new:

/* 
 * 內(nèi)置NEW的實(shí)現(xiàn)原理 
 * @params
 *  Func:操作的那個(gè)類(lèi)
 *  ARGS:NEW類(lèi)的時(shí)候傳遞的實(shí)參集合
 * @return
 *  實(shí)例或者自己返回的對(duì)象
 */
function _new(Func, ...args) {
  //默認(rèn)創(chuàng)建一個(gè)實(shí)例對(duì)象(而且是屬于當(dāng)前這個(gè)類(lèi)的一個(gè)實(shí)例)
  let obj = {};

  //也會(huì)把類(lèi)當(dāng)做普通函數(shù)執(zhí)行
  //執(zhí)行的時(shí)候要保證函數(shù)中的this指向創(chuàng)建的實(shí)例
  let result = Func.call(obj, ...args);

  //若客戶(hù)自己返回引用值,則以自己返回的為主,否則返回創(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è)類(lèi)
 *  ARGS:NEW類(lèi)的時(shí)候傳遞的實(shí)參集合
 * @return
 *  實(shí)例或者自己返回的對(duì)象
 */
function _new(Func, ...args) {
  //默認(rèn)創(chuàng)建一個(gè)實(shí)例對(duì)象(而且是屬于當(dāng)前這個(gè)類(lèi)的一個(gè)實(shí)例)
  // let obj = {};
  let obj = Object.create(Func.prototype);

  //也會(huì)把類(lèi)當(dāng)做普通函數(shù)執(zhí)行
  //執(zhí)行的時(shí)候要保證函數(shù)中的this指向創(chuàng)建的實(shí)例
  let result = Func.call(obj, ...args);

  //若客戶(hù)自己返回引用值,則以自己返回的為主,否則返回創(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)原理及重寫(xiě),希望對(duì)大家有所幫助,也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

最新評(píng)論