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

資訊專欄INFORMATION COLUMN

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

劉明 / 1687人閱讀

摘要:但是三作為構(gòu)造函數(shù)時函數(shù)其實還有一個非常重要的特點返回的函數(shù)如果作為構(gòu)造函數(shù),搭配關(guān)鍵字出現(xiàn)的話,我們的綁定就需要被忽略。其次,當返回的函數(shù)作為構(gòu)造函數(shù)時,之前綁定的會失效。

本文共 1100 字,讀完只需 4 分鐘
概述

前一篇文章我們嘗試模擬實現(xiàn)了 call 和 apply 方法,其實 bind 函數(shù)也可以用來改變 this 的指向。bind 和 call和 apply 兩者的區(qū)別在于,bind 會返回一個被改變了 this 指向的函數(shù)。

本文介紹如何模擬實現(xiàn) bind 函數(shù):

首先觀察 bind 函數(shù)有什么特點:

var person = {
    name: "jayChou"
}

function say(age, sex) {
    console.log(this.name, age, sex);
}

var foo = say.bind(person, "男", 39);

foo();  // jayChou 男 39

返回一個函數(shù)

函數(shù)參數(shù)以逗號的形式傳入

改變了 this 的指向

一、call 簡單實現(xiàn)

既然 bind 內(nèi)部也要用改變 this 指向,我們可以用現(xiàn)成的 call 函數(shù)來實現(xiàn)這一功能。

Function.prototype.newBind = function(context) {
    if(typeof this !== "function") {
        throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    }
    var self = this;
    return function () {
        return self.call(context)
      }
}

說明一下:
if 判斷是為了校驗,只能讓函數(shù)來調(diào)用此方法,并拋出錯誤。
第二個 return 是為了讓返回的函數(shù)有返回值的功能。

測試一下:

var person = {
    name: "jayChou"
};

var say = function() {
    console.log(this.name);
}

var foo = say.newBind(person);
foo();  // jayChou

成功啦。

二、傳遞參數(shù)

剛才的函數(shù)是沒有傳遞參數(shù),當然不行,所以我們想辦法把函數(shù)的參數(shù)也傳遞進去。

bind 函數(shù)有個特點,就是在綁定的時候可以傳參,返回的函數(shù)還可以繼續(xù)傳參。

var person = {
    name: "jayChou"
};

var say = function(p1, p2) {
    console.log(this.name, p1, p2);
}

var foo = say.bind(person, 18);
foo(20);  // jayChou 18 20

還可以寫成:

say.bind(person, 18)(20); // jayChou 18 20

好,進入正題,考慮傳參的事。在前面的文章,我們講過 arguments 類數(shù)組對象的一些特性,不能直接調(diào)用數(shù)組的方法,但是可以用原型方法間接來調(diào)用,我們采用 apply 的方式來傳遞參數(shù)。

Function.prototype.newBind = function(context) {
    if(typeof this !== "function") {
        throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    }
    var self = this;
    var args = Array.prototype.slice.call(arguments, 1);  // 間接調(diào)用數(shù)組方法,獲取第一次傳的參數(shù)
    
    return function () {
        var innerArgs = Array.prototype.slice.call(arguments);
        return self.apply(context, args.concat(innerArgs))
      }
}


var person = {
    name: "jayChou"
};

var say = function(p1, p2) {
    console.log(this.name, p1, p2);
}

var foo = say.newBind(person, 18);  // 第一次傳參
foo(20);  // 第二次傳參

最后輸出:

jayChou 18 20

結(jié)果正確,以上就完成了 bind 函數(shù)基本功能的實現(xiàn)。

但是!

三、作為構(gòu)造函數(shù)時?

bind 函數(shù)其實還有一個非常重要的特點:

bind返回的函數(shù)如果作為構(gòu)造函數(shù),搭配new關(guān)鍵字出現(xiàn)的話,我們的綁定this就需要“被忽略”。

意思就是指:當使用 nuw 關(guān)鍵字把 bind 返回的函數(shù)作為構(gòu)造函數(shù),之前改變了指向的 this 就失效了。返回的函數(shù)的 this 就關(guān)聯(lián)到了構(gòu)造函數(shù)的實例對象上。

針對這個特點,需要再做一些修改:

Function.prototype.newBind = function(context) {
    if(typeof this !== "function") {
        throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    }
    var self = this;
    var args = Array.prototype.slice.call(arguments, 1);  // 間接調(diào)用數(shù)組方法,獲取第一次傳的參數(shù)
    
    let tempFn = function {};  // 利用一個空函數(shù)作為中轉(zhuǎn)
    
    tempFn.prototype = this.prototype;  // 修改返回函數(shù)的 prototype 為綁定函數(shù)的 prototype,實例就可以繼承綁定函數(shù)的原型中的值
    
    var resultFn = function () {
        var innerArgs = Array.prototype.slice.call(arguments);
        if (this instanceof tempFn) {  // 如果 返回函數(shù)被當做構(gòu)造函數(shù)后,生成的對象是 tempFn 的實例,此時應(yīng)該將 this 的指向指向創(chuàng)建的實例。
            return self.apply(this, args.concat(innerArgs));
        } else {
            return self.apply(context, args.concat(innerArgs))
        }
      }
      
    resultFn = new tempFn();
    return resultFn;
}
總結(jié)

本文嘗試模擬實現(xiàn)了 bind 函數(shù),bind 函數(shù)與 call,apply 函數(shù)的區(qū)別在于,bind 函數(shù)返回一個指定了 this 的函數(shù),函數(shù)并未執(zhí)行。其次,當返回的函數(shù)作為構(gòu)造函數(shù)時,之前綁定的 this 會失效。

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

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

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

相關(guān)文章

  • JavaScript深入系列15篇正式完結(jié)!

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

    fxp 評論0 收藏0
  • JS專題數(shù)組去重

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

    only_do 評論0 收藏0
  • JavaScript專題偏函數(shù)

    摘要:專題系列第十四篇,講解偏函數(shù)以及如何實現(xiàn)一個函數(shù)定義維基百科中對偏函數(shù)的定義為翻譯成中文在計算機科學中,局部應(yīng)用是指固定一個函數(shù)的一些參數(shù),然后產(chǎn)生另一個更小元的函數(shù)。 JavaScript 專題系列第十四篇,講解偏函數(shù)以及如何實現(xiàn)一個 partial 函數(shù) 定義 維基百科中對偏函數(shù) (Partial application) 的定義為: In computer science, pa...

    beita 評論0 收藏0
  • 【進階 6-2 期】深入高階函數(shù)應(yīng)用柯里化

    摘要:引言上一節(jié)介紹了高階函數(shù)的定義,并結(jié)合實例說明了使用高階函數(shù)和不使用高階函數(shù)的情況。我們期望函數(shù)輸出,但是實際上調(diào)用柯里化函數(shù)時,所以調(diào)用時就已經(jīng)執(zhí)行并輸出了,而不是理想中的返回閉包函數(shù),所以后續(xù)調(diào)用將會報錯。引言 上一節(jié)介紹了高階函數(shù)的定義,并結(jié)合實例說明了使用高階函數(shù)和不使用高階函數(shù)的情況。后面幾部分將結(jié)合實際應(yīng)用場景介紹高階函數(shù)的應(yīng)用,本節(jié)先來聊聊函數(shù)柯里化,通過介紹其定義、比較常見的...

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

    摘要:模擬實現(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)容對自己提升挺大,但我總覺得,一直埋著頭走路,偶爾也...

    pingink 評論0 收藏0

發(fā)表評論

0條評論

劉明

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<