成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript專題之模擬實現(xiàn)new

pingink / 1260人閱讀

摘要:模擬實現(xiàn)操作符構(gòu)造函數(shù)返回結(jié)果創(chuàng)建一個空對象取傳入的第一個參數(shù),即構(gòu)造函數(shù),并刪除第一個參數(shù)。二處理返回值構(gòu)造函數(shù)也是函數(shù),有不同類型返回值。有時候構(gòu)造函數(shù)會返回指定的對象內(nèi)容,所以要對這部分進行處理。

本文共 1230 字,讀完只需 5 分鐘

寫在前面

最近工作太忙,快接近兩周沒更新博客,總感覺有一些事情等著自己去做,雖然工作內(nèi)容對自己提升挺大,但我總覺得,一直埋著頭走路,偶爾也需要抬起頭來,看看現(xiàn)在和自己的期望向是否脫軌,所以周末還是選擇來星巴克寫些文字。

今天記錄 JavaScript 中 new 關(guān)鍵字的模擬實現(xiàn),當(dāng)我們在模擬實現(xiàn)某個語言行為之前,應(yīng)該想想這個行為都做了哪些事情,通過實踐,最后也能更加掌握知識點,這就是很多面試題都會問到模擬實現(xiàn)的原因,目的是為了考察候選人知識的深度。

function Person(name) {
    this.name = name;
}

var person = new Person("jayChou");

typeof(person)  // "object"
person instanceof Person  // true
person.__proto__ === Person.prototype  // true
person.constructor === Person  //  true
person.constructor === Person.prototype.constructor  // true

以上,可以看出:

new 創(chuàng)建并返回了一個新對象,是構(gòu)造函數(shù)的實例

對象的實例的構(gòu)造函數(shù)屬性其實是構(gòu)造函數(shù)的原型對象的 constructor 屬性

對象實例的 __proto__ 關(guān)聯(lián)到構(gòu)造函數(shù)的原型對象

上面的內(nèi)容有關(guān)于 JavaScript 中原型對象和原型鏈的知識,不夠清楚的同學(xué)可以查看我之前的博客。

由于 new 是 JS 的一個關(guān)鍵字,我們無法實現(xiàn)關(guān)鍵字,但我們可以通過函數(shù)的形式來模擬 new 關(guān)鍵字的行為。

一、基本思路

知道 new 關(guān)鍵字做了哪些工作,那我們就有了模擬實現(xiàn)的基本思路。

/**
 * 模擬實現(xiàn) JavaScript new 操作符
 * @param  {Function} constructor [構(gòu)造函數(shù)]
 * @return {Object|Function|Regex|Date|Error}      [返回結(jié)果]
 */
function mockNew() {
    // 創(chuàng)建一個空對象
    let resultObj = new Object();

    // 取傳入的第一個參數(shù),即構(gòu)造函數(shù),并刪除第一個參數(shù)。
    // 關(guān)于為什么要用 Array.prototype.shift.call 的形式,見之前的博客文章 《JavaScript之a(chǎn)rguments》
    let constructor =  Array.prototype.shift.call(arguments);
    
    // 類型判斷,錯誤處理
    if(typeof constructor !== "function") {
        throw("構(gòu)造函數(shù)第一個參數(shù)應(yīng)為函數(shù)");
    }
    
    // 綁定 constructor 屬性
    resultObj.constructor = constructor;
    
    // 關(guān)聯(lián) __proto__ 到 constructor.prototype
    resultObj.__proto__ = constructor.prototype;
    
    // 將構(gòu)造函數(shù)的 this 指向返回的對象
    constructor.apply(resultObj, arguments);
    
    // 返回對象
    return resultObj;
}

function Person(name) {
    this.name = name;
}


var person = mockNew(Person, "jayChou");

console.log(person);

// constructor: ? Person(name)
// name: "jayChou"
// __proto__: Object

基本思路正確! 所以我們完成了 new 關(guān)鍵字的初步模擬?;锇閭兛梢宰约簞邮智靡幌拢烤浯a自己是否都能理解。

二、處理返回值

構(gòu)造函數(shù)也是函數(shù),有不同類型返回值。有時候構(gòu)造函數(shù)會返回指定的對象內(nèi)容,所以要對這部分進行處理。

/**
 * 模擬實現(xiàn) JavaScript new 操作符
 * @param  {Function} constructor [構(gòu)造函數(shù)]
 * @return {Object|Function|Regex|Date|Error}      [返回結(jié)果]
 */
function mockNew() {
    // 創(chuàng)建一個空對象
    let emptyObj = new Object();

    // 取傳入的第一個參數(shù),即構(gòu)造函數(shù),并刪除第一個參數(shù)。
    // 關(guān)于為什么要用 Array.prototype.shift.call 的形式,見之前的博客文章 《JavaScript之a(chǎn)rguments》
    let constructor =  Array.prototype.shift.call(arguments);
    
    // 類型判斷,錯誤處理
    if(typeof constructor !== "function") {
        throw("構(gòu)造函數(shù)第一個參數(shù)應(yīng)為函數(shù)");
    }
    
    // 綁定 constructor 屬性
    emptyObj.constructor = constructor;
    
    // 關(guān)聯(lián) __proto__ 到 constructor.prototype
    emptyObj.__proto__ = constructor.prototype;
    
    // 將構(gòu)造函數(shù)的 this 指向返回的對象
    let resultObj = constructor.apply(emptyObj, arguments);
    
    // 返回類型判斷, 如果是對象,則返回構(gòu)造函數(shù)返回的對象
    if (typeof resultObj === "object") {
        return resultObj
    }
    
    // 返回對象
    return emptyObj;
}

function Person(name) {
    this.name = name;
    return {
        name: this.name,
        age: 40
    }
}


var person = mockNew(Person, "jayChou");

console.log(person);

// {name: "jayChou", age: 40}
// age: 40
// name: "jayChou"
// __proto__: Object

當(dāng)返回值返回了一個自定義對象后,模擬 new 函數(shù)就返回該自定義對象。

總結(jié)

JavaScript new 關(guān)鍵字的意義在于讓普通函數(shù)生成一個新對象,并將對象實例的 __proto__ 關(guān)聯(lián)到函數(shù)的 prototype 對象。

本文中有些地方需要一些前置知識,但是總體上理解是比較容易的。如果有迷惑的地方,可以翻看我之前的博客文章

歡迎關(guān)注我的個人公眾號“謝南波”,專注分享原創(chuàng)文章。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/99155.html

相關(guān)文章

  • JS專題數(shù)組去重

    摘要:將元素作為對象的鍵,默認(rèn)鍵對應(yīng)的值為如果對象中沒有這個鍵,則將這個元素放入結(jié)果數(shù)組中去。 前言 數(shù)組去重在日常開發(fā)中的使用頻率還是較高的,也是網(wǎng)上隨便一抓一大把的話題,所以,我寫這篇文章目的在于歸納和總結(jié),既然很多人都在提的數(shù)組去重,自己到底了解多少呢。又或者是如果自己在開發(fā)中遇到了去重的需求,自己能想到更好的解決方案嗎。 這次我們來理一理怎么做數(shù)組去重才能做得最合適,既要考慮兼容性,...

    only_do 評論0 收藏0
  • JavaScript專題模擬實現(xiàn)bind

    摘要:但是三作為構(gòu)造函數(shù)時函數(shù)其實還有一個非常重要的特點返回的函數(shù)如果作為構(gòu)造函數(shù),搭配關(guān)鍵字出現(xiàn)的話,我們的綁定就需要被忽略。其次,當(dāng)返回的函數(shù)作為構(gòu)造函數(shù)時,之前綁定的會失效。 本文共 1100 字,讀完只需 4 分鐘 概述 前一篇文章我們嘗試模擬實現(xiàn)了 call 和 apply 方法,其實 bind 函數(shù)也可以用來改變 this 的指向。bind 和 call和 apply 兩者的區(qū)別...

    劉明 評論0 收藏0
  • JavaScript深入系列15篇正式完結(jié)!

    摘要:寫在前面深入系列共計篇已經(jīng)正式完結(jié),這是一個旨在幫助大家,其實也是幫助自己捋順底層知識的系列。深入系列自月日發(fā)布第一篇文章,到月日發(fā)布最后一篇,感謝各位朋友的收藏點贊,鼓勵指正。 寫在前面 JavaScript 深入系列共計 15 篇已經(jīng)正式完結(jié),這是一個旨在幫助大家,其實也是幫助自己捋順 JavaScript 底層知識的系列。重點講解了如原型、作用域、執(zhí)行上下文、變量對象、this、...

    fxp 評論0 收藏0
  • JavaScript專題遞歸

    摘要:專題系列第十八篇,講解遞歸和尾遞歸定義程序調(diào)用自身的編程技巧稱為遞歸。然而非尾調(diào)用函數(shù),就會創(chuàng)建多個執(zhí)行上下文壓入執(zhí)行上下文棧。所以我們只用把階乘函數(shù)改造成一個尾遞歸形式,就可以避免創(chuàng)建那么多的執(zhí)行上下文。 JavaScript 專題系列第十八篇,講解遞歸和尾遞歸 定義 程序調(diào)用自身的編程技巧稱為遞歸(recursion)。 階乘 以階乘為例: function factorial(n...

    asoren 評論0 收藏0
  • JavaScript專題模擬實現(xiàn)call和apply

    摘要:函數(shù)可計算某個字符串,并執(zhí)行其中的的代碼男男成功啦實現(xiàn)了函數(shù)參數(shù)的傳遞,那么函數(shù)返回值怎么處理呢。而且,如果傳入的對象是,又該如何處理所以還需要再做一些工作處理返回值返回返回值男男判斷傳入對象的類型,如果為就指向?qū)ο蟆? 本文共 1320 字,讀完只需 5 分鐘 概述 JS 函數(shù) call 和 apply 用來手動改變 this 的指向,call 和 apply 唯一的區(qū)別就在于函數(shù)...

    ky0ncheng 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<