摘要:那模擬實(shí)現(xiàn)這個(gè)時(shí)候的指調(diào)用的時(shí)候傳入的參數(shù)這兩點(diǎn)完成后,還有一個(gè)特點(diǎn),就是一個(gè)綁定函數(shù)也能使用操作符創(chuàng)建對(duì)象,提供的值被忽略,同時(shí)調(diào)用時(shí)的參數(shù)被提供給模擬函數(shù)。
apply
apply的方法和 call 方法的實(shí)現(xiàn)類(lèi)似,只不過(guò)是如果有參數(shù),以數(shù)組形式進(jìn)行傳遞,直接上代碼:
Function.prototype.apply2 = function(context) { var context = context || window context.fn = this // this 也就是調(diào)用apply的函數(shù) var result // 判斷是否有第二個(gè)參數(shù) if(arguments[1]) { result = context.fn(...arguments[1]) } else { result = context.fn() } delete context.fn() return result } var foo = { value: 1 } function bar(name, age) { console.log(name) console.log(age) console.log(this.value); } bar.apply2(foo, ["black", "18"]) // black 18 1bind
bind() 方法會(huì)創(chuàng)建一個(gè)新的函數(shù)。當(dāng)這個(gè)新函數(shù)被調(diào)用時(shí),bind() 的第一個(gè)參數(shù)會(huì)作為它運(yùn)行時(shí)的this,之后的參數(shù)將會(huì)在傳遞的實(shí)參前傳入作為它的參數(shù)。
也就是說(shuō)bind可以返回一個(gè)函數(shù),并且可以傳入?yún)?shù)。
首先根據(jù)第一點(diǎn),需要返回一個(gè)函數(shù):
Function.prototype.bind2 = function(context) { var self = this return function() { self.apply(context) } } var foo = { value: 1 }; function bar() { console.log(this.value); } var bindFoo = bar.bind2(foo); bindFoo() // 1
接下來(lái)還有第二點(diǎn),可以傳入?yún)?shù),可是傳參數(shù)還會(huì)有兩種情況,是在bind的時(shí)候傳參數(shù)呢,還是在調(diào)用返回的函數(shù)的時(shí)候傳參數(shù)呢?
var foo = { value: 1 }; function bar(name, age) { console.log(name); console.log(age); console.log(this.value); } var bindFoo = bar.bind(foo, "black"); bindFoo("18") // black // 18 // 1
通過(guò)上面的例子就可以明顯發(fā)現(xiàn)。兩種方式都可以傳參。那模擬實(shí)現(xiàn):
Function.prototype.bind2 = function(context) { var self = this var args = [...arguments].slice(1) console.log([...arguments]) return function() { // 這個(gè)時(shí)候的arguments指調(diào)用的時(shí)候傳入的參數(shù) self.apply(context, args.concat([...arguments])) } } var foo = { value: 1 }; function bar(name, age) { console.log(name); console.log(age); console.log(this.value); } var bindFoo = bar.bind2(foo, "black"); bindFoo("18")
這兩點(diǎn)完成后,還有一個(gè)特點(diǎn),就是一個(gè)綁定函數(shù)也能使用new操作符創(chuàng)建對(duì)象,提供的this值被忽略,同時(shí)調(diào)用時(shí)的參數(shù)被提供給模擬函數(shù)。
也就是說(shuō) bind 返回的函數(shù)作為構(gòu)造函數(shù)的時(shí)候,bind 時(shí)指定的 this 值會(huì)失效,但是傳入的參數(shù)依然生效,舉個(gè)例子來(lái)說(shuō)明:
var value = 2; var foo = { value: 1 } function bar(name, age) { console.log(name) console.log(age) console.log(this.value) } bar.prototype.sex = "boy" var bindFoo = bar.bind(foo, "black") var obj = new bindFoo("18") // black // 18 // undefined console.log(obj.sex) // boy
盡管在全局和 foo 中都聲明了 value 值,最后依然返回 undefined,那是因?yàn)楫?dāng)調(diào)用obj的時(shí)候,這個(gè)時(shí)候的this指向已經(jīng)指向到了 obj
所以我們要去修改一下返回函數(shù)的原型來(lái)去實(shí)現(xiàn):
Function.prototype.bind2 = function(context) { var self = this; var args = [...arguments].slice(1) var fun = function() { // 當(dāng)作為構(gòu)造函數(shù)的時(shí)候,this 指向?qū)嵗?self指向綁定函數(shù),由fun.prototype = this.prototype, 使 fun.prototype 為 綁定函數(shù)的 prototype,此時(shí)結(jié)果為true,所以this指向?qū)嵗? // 作為普通函數(shù)時(shí),this 指向window, self 指向綁定函數(shù),此時(shí)結(jié)果為false,此時(shí)this指向綁定的context self.apply(this instanceof self ? this : context,args.concat(...arguments)) } // 修改返回函數(shù)的 prototype 為綁定函數(shù)的 prototype,實(shí)例就可以繼承函數(shù)的原型中的值 // 使用Object.create避免修改函數(shù)的prototype fun.prototype = Object.create(this.prototype) return fun }
最后加個(gè)對(duì)調(diào)用bind是否是個(gè)函數(shù)的判斷:
Function.prototype.bind2 = function(context) { if(typeof this !== "function") { throw new TypeError("Error") } var self = this; var args = [...arguments].slice(1) var fun = function() { // 當(dāng)作為構(gòu)造函數(shù)的時(shí)候,this 指向?qū)嵗?self指向綁定函數(shù),由fun.prototype = this.prototype, 使 fun.prototype 為 綁定函數(shù)的 prototype,此時(shí)結(jié)果為true,所以this指向?qū)嵗? // 作為普通函數(shù)時(shí),this 指向window, self 指向綁定函數(shù),此時(shí)結(jié)果為false,此時(shí)this指向綁定的context self.apply(this instanceof self ? this : context,args.concat(...arguments)) } // 修改返回函數(shù)的 prototype 為綁定函數(shù)的 prototype,實(shí)例就可以繼承函數(shù)的原型中的值 // 使用Object.create避免修改函數(shù)的prototype fun.prototype = Object.create(this.prototype) return fun }
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/97109.html
摘要:也就是說(shuō)當(dāng)返回的函數(shù)作為構(gòu)造函數(shù)的時(shí)候,時(shí)指定的值會(huì)失效,但傳入的參數(shù)依然生效。構(gòu)造函數(shù)效果的優(yōu)化實(shí)現(xiàn)但是在這個(gè)寫(xiě)法中,我們直接將,我們直接修改的時(shí)候,也會(huì)直接修改函數(shù)的。 JavaScript深入系列第十一篇,通過(guò)bind函數(shù)的模擬實(shí)現(xiàn),帶大家真正了解bind的特性 bind 一句話(huà)介紹 bind: bind() 方法會(huì)創(chuàng)建一個(gè)新函數(shù)。當(dāng)這個(gè)新函數(shù)被調(diào)用時(shí),bind() 的第一個(gè)參數(shù)...
摘要:點(diǎn)擊那么面試官可能會(huì)問(wèn)是否想過(guò)到底做了什么,怎么模擬實(shí)現(xiàn)呢。另外前不久寫(xiě)過(guò)一篇文章面試官問(wèn)能否模擬實(shí)現(xiàn)的操作符。所以相當(dāng)于調(diào)用時(shí),的返回值函數(shù)內(nèi)部要模擬實(shí)現(xiàn)實(shí)現(xiàn)的操作。文章中的例子和測(cè)試代碼放在中模擬實(shí)現(xiàn)。 前言 用過(guò)React的同學(xué)都知道,經(jīng)常會(huì)使用bind來(lái)綁定this。 import React, { Component } from react; class TodoItem ...
摘要:返回的綁定函數(shù)也能使用操作符創(chuàng)建對(duì)象這種行為就像把原函數(shù)當(dāng)成構(gòu)造器,提供的值被忽略,同時(shí)調(diào)用時(shí)的參數(shù)被提供給模擬函數(shù)。 bind() bind() 方法會(huì)創(chuàng)建一個(gè)新函數(shù),當(dāng)這個(gè)新函數(shù)被調(diào)用時(shí),它的 this 值是傳遞給 bind() 的第一個(gè)參數(shù),傳入bind方法的第二個(gè)以及以后的參數(shù)加上綁定函數(shù)運(yùn)行時(shí)本身的參數(shù)按照順序作為原函數(shù)的參數(shù)來(lái)調(diào)用原函數(shù)。bind返回的綁定函數(shù)也能使用 n...
摘要:但是三作為構(gòu)造函數(shù)時(shí)函數(shù)其實(shí)還有一個(gè)非常重要的特點(diǎn)返回的函數(shù)如果作為構(gòu)造函數(shù),搭配關(guān)鍵字出現(xiàn)的話(huà),我們的綁定就需要被忽略。其次,當(dāng)返回的函數(shù)作為構(gòu)造函數(shù)時(shí),之前綁定的會(huì)失效。 本文共 1100 字,讀完只需 4 分鐘 概述 前一篇文章我們嘗試模擬實(shí)現(xiàn)了 call 和 apply 方法,其實(shí) bind 函數(shù)也可以用來(lái)改變 this 的指向。bind 和 call和 apply 兩者的區(qū)別...
摘要:模擬和模擬一樣,現(xiàn)摘抄下面的代碼添加一個(gè)返回值對(duì)象然后我們定義一個(gè)函數(shù),如果執(zhí)行下面的代碼能夠返回和函數(shù)一樣的值,就達(dá)到我們的目的。 原文:https://zhehuaxuan.github.io/... 作者:zhehuaxuan 目的 本文主要用于理解和掌握call,apply和bind的使用和原理,本文適用于對(duì)它們的用法不是很熟悉,或者想搞清楚它們?cè)淼耐? 好,那我們開(kāi)始...
閱讀 1391·2023-04-26 03:04
閱讀 2325·2019-08-30 15:44
閱讀 3727·2019-08-30 14:15
閱讀 3507·2019-08-27 10:56
閱讀 2703·2019-08-26 13:53
閱讀 2616·2019-08-26 13:26
閱讀 3075·2019-08-26 12:11
閱讀 3609·2019-08-23 18:21