摘要:對中和三個方法的解讀中,和都是為了改變某個函數(shù)運行時的上下文而存在的,其實就是為了改變所調(diào)用的函數(shù)體內(nèi)部的指向。
對ES5中apply、call和bind三個方法的解讀
JavaScript中,apply、call 和 bind 都是為了改變某個函數(shù)運行時的上下文而存在的,其實就是為了改變所調(diào)用的函數(shù)體內(nèi)部 this 的指向。
Function.prototype.apply()方法Example
var nodeList = document.querySelectorAll("div"); Array.prototype.slice.apply(nodeList).forEach((node)=>{ console.log(node); // 輸出每一個div節(jié)點對象 });
代碼解讀:
上面是一段JS中常用的代碼,這段代碼表示的意義是,當(dāng)我們獲取到一個類數(shù)組的對象的時候如何讓它可以調(diào)用所有數(shù)組所擁有的方法。我們都知道,所有的獲取dom元素的方法,返回的不是dom節(jié)點對象,就是包含節(jié)點對象的類數(shù)組,而類數(shù)組雖然從輸出來看和數(shù)組是沒什么區(qū)別的,但是在原型鏈上是有很大的差異的。像NodeList這個類數(shù)組就是不包含基本上所有數(shù)組的常用方法的,所以這個時候就需要 借 數(shù)組的slice方法來將NodeList這個歌類數(shù)組轉(zhuǎn)成真正的數(shù)組對象,這樣就可以直接調(diào)用push方法了。
Example
var nodeList = document.querySelectorAll("div"); Array.prototype.slice.call(nodeList).forEach((node)=>{ console.log(node); // 輸出每一個div節(jié)點對象 });
代碼解讀:上面這段代碼和apply方法中的例子是一模一樣的,所以,其實他們兩個方法的作用都是一致的,用法呢就是類似的,而為什么說是類似的呢,看下面這個例子:
Example:
var max1 = Math.max.call(null, 1,2,3); var max2 = Math.max.apply(null, [1,2,3]); console.log(max1); // 結(jié)果是3 console.log(max2) // 結(jié)果是3
代碼解讀:從上面這個例子中可以看出,call和apply的用法不同之處在于,如果所調(diào)用的方法方法需要傳入?yún)?shù),那么call需要從第二個入?yún)㈤_始傳入需要的值,而apply是在第二入?yún)⒂?strong>數(shù)組來傳遞參數(shù),這里要注意的是哪怕是參數(shù)只需要傳入一個,也全都按照這種語法規(guī)則,不然如上面的Math.max就會報TypeError,所以建議如下:當(dāng)所調(diào)用的方法是0個參數(shù)的,那隨便哪個都可以,如果是1~2個參數(shù)的建議使用call方法,如果是3個及以上的用apply方法。
Function.prototype.bind()方法Example
var nodeList = document.querySelectorAll("div"); var nodeArray = Array.prototype.slice.bind(nodeList); nodeArray().forEach((node)=>{ console.log(node); // 輸出每一個div節(jié)點對象 });
代碼解讀:從上面的例子看一看出bind方法只是替換了所調(diào)用方法的this指向,并不會主動去執(zhí)行這個方法,而apply和call方法是即改變了this指向,又立即執(zhí)行的,所以bind一般用于不需要立即執(zhí)行,只要求更改this指向的場景,如:click事件的回調(diào)函數(shù)一般就會用bind去改變回調(diào)函數(shù)的this指向,而在click事件觸發(fā)的時候執(zhí)行。最后說明一下,bind的參數(shù)和call的參數(shù)傳遞是一致的,例子如下:
Example
var maxBind = Math.max.bind(null, 1,2,3); var max = maxBind(); console.log(max); // 結(jié)果是3
結(jié)束語:上面就是javaScript對于如何改變運行時上下文的三個方法了,下面是我自己實現(xiàn)的一個類似運行時改變上下文的方法,不適合在實際場景中使用,僅供大家參考:
var Person = { context:null, name:"小明", say:function(greeting){ var me = this.context || this; return greeting + me.name } } Person.say.__proto__.callCopy = function(_context,greeting){ Person.context = _context; return Person.say(greeting); } var world1 =Person.say("你好 "); var world2 = Person.say.callCopy({name:"xiaoMing"},"hello "); console.log(world1); // 你好 小明 console.log(world2); // hello xiaoMing
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/84151.html
摘要:概括地講,如果構(gòu)造函數(shù)有返回值,且返回值是對象不能是,那么對其進(jìn)行操作返回該對象,否則返回構(gòu)造實例。所以在方法中,我們需要進(jìn)一步判斷這個構(gòu)造函數(shù)有沒有返回值,返回值是不是對象。 自從進(jìn)入七月以來,我的 underscore 源碼解讀系列 更新緩慢,再這樣下去,今年更完的目標(biāo)似乎要落空,趕緊寫一篇壓壓驚。 前文 跟大家簡單介紹了下 ES5 中的 bind 方法以及使用場景(沒讀過的同學(xué)建...
摘要:來自朋友去某信用卡管家的做的一道面試題,用原生模擬的方法,不準(zhǔn)用和方法。他們的用途相同,都是在特定的作用域中調(diào)用函數(shù)。不同之處在于,方法傳遞給調(diào)用函數(shù)的參數(shù)是逐個列出的,而則是要寫在數(shù)組中。 本文首發(fā)我的個人博客:前端小密圈,評論交流送1024邀請碼,嘿嘿嘿?。 來自朋友去某信用卡管家的做的一道面試題,用原生JavaScript模擬ES5的bind方法,不準(zhǔn)用call和bind方法。 ...
摘要:來自朋友去某信用卡管家的做的一道面試題,用原生模擬的方法,不準(zhǔn)用和方法。他們的用途相同,都是在特定的作用域中調(diào)用函數(shù)。不同之處在于,方法傳遞給調(diào)用函數(shù)的參數(shù)是逐個列出的,而則是要寫在數(shù)組中。 本文首發(fā)我的個人博客:前端小密圈,評論交流送1024邀請碼,嘿嘿嘿?。 來自朋友去某信用卡管家的做的一道面試題,用原生JavaScript模擬ES5的bind方法,不準(zhǔn)用call和bind方法。 ...
摘要:返回的綁定函數(shù)也能使用操作符創(chuàng)建對象這種行為就像把原函數(shù)當(dāng)成構(gòu)造器。同時,將第一個參數(shù)以外的其他參數(shù),作為提供給原函數(shù)的預(yù)設(shè)參數(shù),這也是基本的顆?;A(chǔ)。 今天想談?wù)勔坏狼岸嗣嬖囶},我做面試官的時候經(jīng)常喜歡用它來考察面試者的基礎(chǔ)是否扎實,以及邏輯、思維能力和臨場表現(xiàn),題目是:模擬實現(xiàn)ES5中原生bind函數(shù)。也許這道題目已經(jīng)不再新鮮,部分讀者也會有思路來解答。社區(qū)上關(guān)于原生bind的研...
閱讀 3524·2021-11-25 09:43
閱讀 1281·2021-09-08 09:45
閱讀 2654·2021-09-07 09:59
閱讀 1516·2021-08-09 13:45
閱讀 3370·2019-08-30 15:54
閱讀 706·2019-08-29 18:35
閱讀 523·2019-08-29 17:18
閱讀 1008·2019-08-29 14:10