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