摘要:關(guān)于的指向的問題請參照我的學(xué)習(xí)筆記。那么在這里事實上都改變了函數(shù)方法被調(diào)用時的指向。那么回調(diào)函數(shù)在執(zhí)行的時候指向還是。大家看完之后應(yīng)該已經(jīng)懂了把還是不懂的話在評論區(qū)留言,我給大家解答。
先從一個小題目開始吧:
要實現(xiàn)一個加法函數(shù),這個時候向函數(shù)當中傳遞個數(shù)大于0的若干個整形數(shù)據(jù),求所有這些數(shù)據(jù)的和。
Function.prototype.call
Function.prototype.apply
Function.prototype.bind
其中call方法:
var personA = { name: "XL", sayName: function (hobby){ console.log(this.name + " likes " + hobby); } }; personA.sayName("basketball"); // "XL likes basketball" var personB = { name: "xl" } personA.sayName.call(personB, "basketball"); // "xl likes basketball" personA.sayName.apply(personB, ["basketball"]); // "xl likes basketball"
call和apply的區(qū)別就在于傳遞方式的不同,call在接收指定參數(shù)的形式是someMethod.call(obj, arg1, arg2);而apply在接收指定參數(shù)時的形式是someMethod.apply(obj, [arg1, arg2]).或者someMethod.apply(obj, arg1),但是這個arg1必須是一個類數(shù)組對象
其實想要真正掌握call/apply包括bind方法,首先必須搞清楚當一個函數(shù)/方法被調(diào)用的時候this的指向問題。 關(guān)于this的指向的問題請參照我的學(xué)習(xí)筆記。
那么在這里call,apply,bind事實上都改變了函數(shù)/方法被調(diào)用時this的指向。
還是拿上面的例子來說:
personA.sayName(‘basketball’); //調(diào)用sayName()這個方法的對象是personA,因此sayName()內(nèi)部的this指向就是personA對象
換一種寫法
var sayName = personA.sayName("basketball"); //這里將sayName方法掛載到了window對象上,即window.sayName = person.sayName(); 這個時候調(diào)用sayName().此時this指向就是window對象
使用call/apply
personA.sayName.call(personB, "basketball"); //本來sayName方法的this指向是personA對象,但是調(diào)用call后,this對象指向了personB對象。
如果大家這種寫法看不習(xí)慣,那就換種方式來看:
personA.sayName.call(personB, "basketball") ===> personB.sayName("basketball"); //從前面的一個形式變?yōu)楹竺嬉环N形式,此時,sayName方法的this指向是personB對象了。
換一種方式書寫后大家應(yīng)該看的很清晰明了了吧?以后碰到call/apply調(diào)用的時候,換一種形式去理解,這樣就很清晰了。
再比如大家經(jīng)常看到的一種對于函數(shù)的arguments類數(shù)組對象的處理方式:
function fn() { var args = Array.prototype.slice.apply(arguments); //這里將arguments這個類數(shù)組對象轉(zhuǎn)化為一個數(shù)組 } //咱們再來轉(zhuǎn)化下: Array.prototype.slice.apply(arguments); ===>>> arguments.slice(); //因為arguments是類數(shù)組對象的原因,因此它可以直接調(diào)用slice方法;如果要截取數(shù)組的從第幾位到第幾位的數(shù) Array.prototype.slice.apply(arguments, [0, 2]); ===>>> arguments.slice(0, 2);
握草,感覺編不下去了- -
其實將call/apply,換一種形式去看,是不是就和普通的方法調(diào)用一樣一樣的。
bind方法呢,起的作用和call,apply一樣,都是改變函數(shù)/方法執(zhí)行時,this的指向,確保這個函數(shù)/方法運行時this指向保持一致。
比如大家經(jīng)常用到的setTimeout異步函數(shù):
var person = { name: "XL", sayName: function() { setTimeout(function() { console.log(this.name); }, 0); } } person.sayName(); //最后輸出: undefined
這是因為setTimeout()這個異步函數(shù)調(diào)用的時候,內(nèi)部的回調(diào)函數(shù)this的指向是window.但是在window對象上并未掛載name屬性,因此最后輸出undefined.
添加一行代碼
var name = "XLLLL"; var person = { name: "XL", sayName: function() { setTimeout(function() { console.log(this.name); }, 0); } } person.sayName(); //輸出 ‘XLLLL’
為了避免在回調(diào)函數(shù)當中,this指向發(fā)生變化,所以大家都會這樣處理:
var person = { name: "XL", sayName: function() { setTimeout(function() { console.log(this.name); }.bind(this), 0); //通過bind方法將this對象綁定為person。那么回調(diào)函數(shù)在執(zhí)行的時候,this指向還是person。 } }
可以用下面這段代碼來簡單模擬下bind方法內(nèi)部的操作:
Function.prototype.bind = function(obj) { var method = this; return function() { method.apply(obj, arguments); } }
還記得剛才給大家講的將apply進行變換的形式嗎?
Function.prototype.bind = function(obj) { var method = this; return function() { obj.method(arguments); } }
大家應(yīng)該看到了bind和apply/call的區(qū)別了吧? bind方法是返回一個新的函數(shù),但是這個函數(shù)比較特殊,這個函數(shù)的this對象已經(jīng)被bind方法傳入的第一個參數(shù)給綁定了.
比如我們可以使用bind方法來簡寫一個方法:
function fn() { var hasOwnKey = Function.call.bind(Object.hasOwnProperty); for(var key in obj) { if(hasOwnKey(obj, key)) { //xxxx } } }
唉,真的編不下去了。大家看完之后應(yīng)該已經(jīng)懂了把? - -
還是不懂的話在評論區(qū)留言,我給大家解答。
哦,一開始那個題目的一種寫法
//要實現(xiàn)一個加法函數(shù),這個時候向函數(shù)當中傳遞個數(shù)大于0的若干個整形數(shù)據(jù),求所有這些數(shù)據(jù)的和。 function add() { return Array.prototype.reduce.call(arguments, function(n1, n2) { return n1 + n2; }); }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/80464.html
摘要:最近剛剛看完了你不知道的上卷,對有了更進一步的了解。你不知道的上卷由兩部分組成,第一部分是作用域和閉包,第二部分是和對象原型。附錄詞法這一章并沒有說明機制,只是介紹了中的箭頭函數(shù)引入的行為詞法。第章混合對象類類理論類的機制類的繼承混入。 最近剛剛看完了《你不知道的 JavaScript》上卷,對 JavaScript 有了更進一步的了解。 《你不知道的 JavaScript》上卷由兩部...
摘要:總結(jié)動態(tài)代理的相關(guān)原理已經(jīng)講解完畢,接下來讓我們回答以下幾個思考題。 【干貨點】 此處是【好好面試】系列文的第12篇文章。文章目標主要是通過原理剖析的方式解答Aop動態(tài)代理的面試熱點問題,通過一步步提出問題和了解原理的方式,我們可以記得更深更牢,進而解決被面試官卡住喉嚨的情況。問題如下 SpringBoot默認代理類型是什么 為什么不用靜態(tài)代理 JDK動態(tài)代理原理 CGLIB動態(tài)代理...
摘要:系統(tǒng),扎實的語言基礎(chǔ)是一個優(yōu)秀的前端工程師必須具備的。第一個參數(shù)為調(diào)用函數(shù)時的指向,隨后的參數(shù)則作為函數(shù)的參數(shù)并調(diào)用,也就是。和的區(qū)別只有一個,就是它只有兩個參數(shù),而且第二個參數(shù)為調(diào)用函數(shù)時的參數(shù)構(gòu)成的數(shù)組。 系統(tǒng),扎實的 javascript 語言基礎(chǔ)是一個優(yōu)秀的前端工程師必須具備的。在看了一些關(guān)于 call,apply,bind 的文章后,我還是打算寫下這篇總結(jié),原因其實有好幾個。...
摘要:包中導(dǎo)出的默認是運行時構(gòu)建。當然,我們期待的是只修改代碼,不用重新運行命令,甚至不需要刷新瀏覽器即看到代碼的改動效果,這時候需要新的插件來配置實現(xiàn)的熱重載。 首先已經(jīng)全局安裝了node/vue/webpack; 新建文件夾demo4并初始化 cd demo4 npm init -y 這是頁面會生成一個package.json文件。 安裝webpack及相關(guān)插件 npm install ...
摘要:綁定書中提到在中,實際上并不存在所謂的構(gòu)造函數(shù),只有對于函數(shù)的構(gòu)造調(diào)用。規(guī)則使用構(gòu)造調(diào)用的時候,會自動綁定在期間創(chuàng)建的對象上。指向新創(chuàng)建的對象綁定比隱式綁定優(yōu)先級高。 showImg(http://ww1.sinaimg.cn/large/005Y4rCogy1fstcwvzkjzj30sg0g0qqn.jpg); 前言 最近正在看《你不知道的JavaScript》,里面關(guān)于this綁...
閱讀 3466·2019-08-30 15:44
閱讀 808·2019-08-30 13:46
閱讀 2097·2019-08-30 11:05
閱讀 3344·2019-08-29 18:32
閱讀 2165·2019-08-29 13:56
閱讀 1304·2019-08-29 12:57
閱讀 770·2019-08-28 18:21
閱讀 1755·2019-08-26 12:16