javascript
JS高级——手写call()、apply()、bind()
0、call、apply、bind的區(qū)別
bind,call,apply的作用都是用來改變this指向的
call方法
call方法的第一個(gè)參數(shù)是this的指向
后面?zhèn)魅氲氖且粋€(gè)參數(shù)列表(注意和apply傳參的區(qū)別)。當(dāng)一個(gè)參數(shù)為null或undefined的時(shí)候,函數(shù)中的this默認(rèn)指向window(在瀏覽器中),和apply一樣,call也只是臨時(shí)改變一次this指向,并立即執(zhí)行。
apply方法:使用apply方法改變this指向后原函數(shù)會(huì)立即執(zhí)行,且此方法只是臨時(shí)改變thi指向一次。
apply接受兩個(gè)參數(shù):
第一個(gè)參數(shù)是this的指向
第二個(gè)參數(shù)是函數(shù)接受的參數(shù),以數(shù)組的形式傳入,且當(dāng)?shù)谝粋€(gè)參數(shù)為null、undefined的時(shí)候,函數(shù)中的this默認(rèn)指向window(在瀏覽器中)
3. bind方法
bind方法和call很相似
第一參數(shù)也是this的指向
后面?zhèn)魅氲囊彩且粋€(gè)參數(shù)列表(但是這個(gè)參數(shù)列表可以分多次傳入,call則必須一次性傳入所有參數(shù)),但是它改變this指向后不會(huì)立即執(zhí)行,而是返回一個(gè)永久改變this指向的函數(shù)。
一、call函數(shù)的實(shí)現(xiàn)
// 給所有的函數(shù)添加一個(gè)myCall方法 Function.prototype.myCall = function (thisArg, ...args) {// 1. 獲取需要被執(zhí)行的函數(shù)var fn = this// 對thisArg轉(zhuǎn)成對象類型(防止它傳入的是非對象類型的參數(shù))thisArg = thisArg ? Object(thisArg) : window// 2.為調(diào)用myCall的函數(shù)綁定this(利用了js的隱式綁定)thisArg.fn = fn// 3.調(diào)用需要被執(zhí)行的函數(shù)const result = thisArg.fn(...args)delete thisArg.fn// 4.將函數(shù)的調(diào)用結(jié)果返回return result }const result = sum.myCall('aaa', 10, 20) console.log(result)function sum(num1, num2) {console.log('sum函數(shù)被執(zhí)行了', this)return num1 + num2 }// const result = sum.call('aaa', 20, 30) // console.log(result)二、apply函數(shù)的實(shí)現(xiàn)
Function.prototype.myApply = function (thisArg, argArr) {// 1. 獲取調(diào)用myApply的函數(shù)var fn = this// 2. 將thisArg轉(zhuǎn)成對象類型,否則后續(xù)無法通過thisArg.fn綁定this,// 且若thisArg沒有傳值,則讓this綁定為windowthisArg = (thisArg !== null && thisArg !== undefined) ? Object(thisArg) : windowthisArg.fn = fn// 3. 對argArr進(jìn)行處理,確保它有傳值并且為數(shù)組,// 否則后續(xù)通過...argArr解構(gòu)會(huì)報(bào)錯(cuò):因?yàn)槿绻鸻rgArr不傳值時(shí)為undefined,...undefined解構(gòu)就會(huì)報(bào)錯(cuò)argArr = argArr ? argArr : []// 4. 執(zhí)行函數(shù)const result = thisArg.fn(...argArr)delete thisArg.fn// 5. 將函數(shù)執(zhí)行結(jié)果返回return result } function sum(num1, num2) {console.log(this, num1, num2)return num1 + num2 } const result1 = sum.myApply('aaa', [10, 20]) console.log(result1) const result2 = sum.myApply(0) console.log(result2) sum.apply('aaa', [10, 20]) sum.apply(0)三、bind函數(shù)的實(shí)現(xiàn)
bind方法和call很相似
第一參數(shù)也是this的指向
后面?zhèn)魅氲囊彩且粋€(gè)參數(shù)列表(但是這個(gè)參數(shù)列表可以分多次傳入,call則必須一次性傳入所有參數(shù)),但是它改變this指向后不會(huì)立即執(zhí)行,而是返回一個(gè)永久改變this指向的函數(shù)。
總結(jié)
以上是生活随笔為你收集整理的JS高级——手写call()、apply()、bind()的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Vue 中的组件缓存
- 下一篇: Nodejs之http模块详解