摘要:但是三作為構(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
摘要:寫在前面深入系列共計篇已經(jīng)正式完結(jié),這是一個旨在幫助大家,其實也是幫助自己捋順底層知識的系列。深入系列自月日發(fā)布第一篇文章,到月日發(fā)布最后一篇,感謝各位朋友的收藏點贊,鼓勵指正。 寫在前面 JavaScript 深入系列共計 15 篇已經(jīng)正式完結(jié),這是一個旨在幫助大家,其實也是幫助自己捋順 JavaScript 底層知識的系列。重點講解了如原型、作用域、執(zhí)行上下文、變量對象、this、...
摘要:將元素作為對象的鍵,默認鍵對應(yīng)的值為如果對象中沒有這個鍵,則將這個元素放入結(jié)果數(shù)組中去。 前言 數(shù)組去重在日常開發(fā)中的使用頻率還是較高的,也是網(wǎng)上隨便一抓一大把的話題,所以,我寫這篇文章目的在于歸納和總結(jié),既然很多人都在提的數(shù)組去重,自己到底了解多少呢。又或者是如果自己在開發(fā)中遇到了去重的需求,自己能想到更好的解決方案嗎。 這次我們來理一理怎么做數(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...
摘要:引言上一節(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ù)柯里化,通過介紹其定義、比較常見的...
摘要:模擬實現(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)容對自己提升挺大,但我總覺得,一直埋著頭走路,偶爾也...
閱讀 2354·2021-11-24 09:39
閱讀 3799·2021-11-19 09:40
閱讀 2173·2021-09-27 13:36
閱讀 1909·2019-08-30 15:44
閱讀 407·2019-08-30 13:52
閱讀 2725·2019-08-30 11:13
閱讀 2207·2019-08-29 16:18
閱讀 1771·2019-08-29 15:43