摘要:而且當時,會把的賦給函數,而函數返回的是,所以這時的也賦給了。實例化總結所以函數總共做了哪幾件事呢沒有實例化時,將傳入對象的參數引用到當前函數,執行當前函數,返回結果實例化時,使用操作生成新函數,原函數的賦給新函數,執行新函數,并返回新函數
文章原地址:https://github.com/catchonme/...
ES5 實現 bind 函數如下
Function.prototype.bind = function(that){ var self = this, args = arguments.length > 1 ? Array.slice(arguments, 1) : null, F = function(){}; var bound = function(){ var context = that, length = arguments.length; if (this instanceof bound){ F.prototype = self.prototype; context = new F; } var result = (!args && !length) ? self.call(context) : self.apply(context, args && length ? args.concat(Array.slice(arguments)) : args || arguments); return context == that ? result : context; }; return bound; }
測試1
var bar = function() { console.log(this.x) } var foo = { x: 3 } var func = bar.bind(foo); func(); // 3
bar 函數綁定foo 中的x 值,然后輸出3
bind 函數中最主要的是bound 函數,bound 函數做了哪些事呢?
首先context 存儲傳入的that 到context 中,判斷this instanceof bound ,那什么時候this instanceof bound == true 呢?在測試1中的案例中,this instanceof bound 為 false ,打印此時的this 輸出Window?{postMessage: ?, blur: ?, focus: ?, close: ?, frames: Window,?…} ,發現是window 對象,因為foo 本身就是在window 對象中。
所以此時直接執行self.call(context) ,返回執行的結果3 ,就是我們測試1中的結果。
那什么時候this instanceof bound == true 呢,而且此時還需要使用空函數F 來獲取主函數的prototype ,
答案是實例化,什么時候實例化呢?
測試2
var bar = function() { console.log(this.x) } bar.prototype.name = function(){ this.name = "name"; } var foo = { x: 3 } var func = bar.bind(foo); var newFunc = new func; // undefined newFunc.name(); // name
對bar.bind(foo) 進行實例化,此時因為進行了new 操作,new 操作做了什么呢,參考new操作符里面到底發生了什么?所以此時的this 為新生成的bound {} 對象,constructor 為bound 函數,所以此時this instanceof bound == true
那為什么bar.bind(foo) 把foo 對象傳遞的時候,沒有輸出3 而是undefined 呢?也是因為new 操作,當前的上下文已經是新生成的newFunc 函數了。而且當this instanceof bound == true 時,會把bar 的prototype 賦給F 函數,而bound 函數返回的是new F ,所以這時bar 的prototype 也賦給newFunc 了。
我們看看ES6的操作,結果和上述例子是一樣的。
var bar = function() { console.log(this.x) } bar.prototype.name = function(){ console.log("name") } var foo = { x: 3 } var func = bar.bind(foo); func(); // 3 // 實例化 var newFunc = new func; // undefined newFunc.name(); // name
總結:
所以bind 函數總共做了哪幾件事呢?
沒有實例化時,將傳入對象的參數引用到當前函數,執行當前函數,返回結果
實例化時,使用new 操作生成新函數,原函數的prototype 賦給新函數,執行新函數,并返回新函數
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/94678.html
摘要:前端基本功示例代碼一點這里前端基本功示例代碼二點這里一像素偽類實現對于老項目,有沒有什么辦法能兼容的尷尬問題了,個人認為偽類是比較完美的方法了。 前端基本功-示例代碼 (一) 點這里前端基本功-示例代碼 (二) 點這里 1.一像素 偽類 + transform 實現對于老項目,有沒有什么辦法能兼容1px的尷尬問題了,個人認為偽類+transform是比較完美的方法了。 原理是把原先元素...
摘要:前端基本功示例代碼一點這里前端基本功示例代碼二點這里一像素偽類實現對于老項目,有沒有什么辦法能兼容的尷尬問題了,個人認為偽類是比較完美的方法了。 前端基本功-示例代碼 (一) 點這里前端基本功-示例代碼 (二) 點這里 1.一像素 偽類 + transform 實現對于老項目,有沒有什么辦法能兼容1px的尷尬問題了,個人認為偽類+transform是比較完美的方法了。 原理是把原先元素...
摘要:簡單的函數調用顯而易見,一直用調用函數將會非常煩人。規范說幾乎總是被傳遞,但不在嚴格模式下時被調用函數應該將其更改為全局對象。實際上,規范有一個和都使用的原語內部稱為。 過去很多年里,我看到過太多關于JavaScript函數調用的混淆。尤其是,很多人抱怨函數調用中this的語義令人困惑。在我看來,通過理解核心函數調用原語,然后將其他所有調用函數的方法視為在原語之上的語法糖,如此便可澄清...
摘要:聲明的變量不得改變值,這意味著,一旦聲明變量,就必須立即初始化,不能留到以后賦值。 雖然今年沒有換工作的打算 但為了跟上時代的腳步 還是忍不住整理了一份最新前端知識點 知識點匯總 1.HTML HTML5新特性,語義化瀏覽器的標準模式和怪異模式xhtml和html的區別使用data-的好處meta標簽canvasHTML廢棄的標簽IE6 bug,和一些定位寫法css js放置位置和原因...
摘要:聲明的變量不得改變值,這意味著,一旦聲明變量,就必須立即初始化,不能留到以后賦值。 雖然今年沒有換工作的打算 但為了跟上時代的腳步 還是忍不住整理了一份最新前端知識點 知識點匯總 1.HTML HTML5新特性,語義化瀏覽器的標準模式和怪異模式xhtml和html的區別使用data-的好處meta標簽canvasHTML廢棄的標簽IE6 bug,和一些定位寫法css js放置位置和原因...
閱讀 890·2023-04-26 02:16
閱讀 1199·2019-08-30 15:55
閱讀 2788·2019-08-30 15:53
閱讀 3382·2019-08-29 15:38
閱讀 2885·2019-08-29 13:42
閱讀 1980·2019-08-26 13:34
閱讀 1835·2019-08-26 10:10
閱讀 3077·2019-08-23 14:40