JS面試中你不知道的call apply bind方法及使用場景詳解
面試
面試官 :說一下 call apply bind 的三者區(qū)別吧?
我:啊.....這。
三者區(qū)別
call
我們先來看看 call
call 函數(shù)接收兩個參數(shù)
@params1
需要指向this
@params2
需要攜帶的參數(shù)
就拿這段代碼 來說 我調(diào)用 foo 函數(shù) 的時候 想去 執(zhí)行obj 中的 eat函數(shù) 怎么辦?
默認(rèn) 我的 foo 里面什么頁面有 怎么可能會打印 吃飯呢?this默認(rèn)指向 window ,window 對象中 沒有 eat 方法不應(yīng)該 報錯 not defind 嗎?
let obj = { eat: function (args) { console.log("吃飯", args); } } function foo(...args) { this.eat(args) }
你可以這樣 , 此時調(diào)用的時候 foo 的函數(shù) this 就指向了 obj 但是只是這一次調(diào)用哦 ,下次 this 是指向 window
的
console.log(foo.call(obj, 123, 456)); / / 吃飯 [ 123, 456 ]
調(diào)用結(jié)果
: 傳入 this 和 參數(shù) 立即執(zhí)行函數(shù)
apply.
@params1
需要指向this
@params2
需要攜帶的參數(shù) 傳入的參數(shù)數(shù)據(jù)類型為 Array
let obj = { eat: function (args) { console.log("吃飯", args); } } function foo(...args) { this.eat(args) }
console.log(foo.apply(obj, [1, 2, 3])); // 吃飯 [1,2,3 ]
調(diào)用結(jié)果
: 傳入 this 和 參數(shù),立即執(zhí)行
bind
@params1
需要指向this
@params2
需要攜帶的參數(shù)
let obj = { eat: function (args) { console.log("吃飯", args); } } function foo(...args) { this.eat(args) }
console.log(foo.bind(obj, 1, 2, 3)()); //吃飯 [ 1, 2, 3 ]
調(diào)用結(jié)果 : 傳入 this 和 參數(shù) 返回一個 新的函數(shù),不會立即執(zhí)行
總結(jié)
call
函數(shù) 傳入綁定 this的對象 ,攜第二個參數(shù)以 參數(shù)列表形式傳入 并會立即執(zhí)行
apply
函數(shù) 傳入綁定 this的對象 第二個參數(shù)以 數(shù)組的形式 傳入 并會立即執(zhí)行
bind
函數(shù) 傳入綁定 this的對象 第二個參數(shù)以 數(shù)組或參數(shù)列表的形式傳入 不會立即執(zhí)行函數(shù)會返回一個新的函數(shù) 自由調(diào)用
應(yīng)用場景
利用call 實(shí)現(xiàn) 構(gòu)造函數(shù)原型繼承
function Person(name, age, friends) { this.friends = friends this.name = name this.age = age } Person.prototype.eat = function () { console.log(`${this.name}在吃飯`); } Person.prototype.running = function () { console.log(`${this.name}去跑步了`); } function Student(study, name, age, friedns) { Person.call(this, name, age, friedns) this.study = study } function Teacher(plaseLoveStudent) { this.plaseLoveStudent = plaseLoveStudent } //繼承 person Student.prototype = new Person() const stu = new Student('語文', "張三", 18, ['王安石']) const stu2 = new Student('數(shù)學(xué)', "李四", 18, ['哈利波特']) const tec = new Teacher("王安怡") console.log(stu === stu2); console.log(stu); console.log(stu.friends); console.log(stu2.friends);
簡單實(shí)現(xiàn)
call
實(shí)現(xiàn)思路 :
1:在Function 原型身上添加一個方法。
2:mycall 接受 兩個參數(shù) 一個是綁定的 this,還有就是 參數(shù)列表
3:保存調(diào)用者,其實(shí)這里更嚴(yán)謹(jǐn)一點(diǎn)還需要判斷調(diào)用者的 類型
4:判斷傳入的thisArgs 是不是 undefined 或者 null 如果是 則 this指向 window 否則將 綁定的 this封裝成 一個對象
5:然后將 函數(shù)本身保存在 上面封裝好的對象中
6:調(diào)用并傳入args
7:完成實(shí)現(xiàn) this指向的改變
Function.prototype.mycall = function (thisArgs, ...args) { /** * * 保存this(當(dāng)前調(diào)用者) * */ const newFunc = this // 在當(dāng)前調(diào)用者 this身上 保存 調(diào)用者 thisArgs = (thisArgs !== undefined && thisArgs !== null) ? Object(thisArgs) : window thisArgs.func = newFunc thisArgs.func(...args) }
apply
apply 就不說了 實(shí)現(xiàn)思路是一樣的 只不過傳入的參數(shù)不一樣做一個判斷就行了
Function.prototype.myapply = function (thisArgs, argArray) { if (!(argArray instanceof Array)) { throw '參數(shù)類型限定為 Array' } else { const func = this thisArgs = (thisArgs !== undefined && thisArgs !== null) ? Object(thisArgs) : window thisArgs.fn = func thisArgs.fn(argArray) } }
bind
bind 跟 apply call 有一些區(qū)別
bind 會返回一個新的函數(shù) , 所以我們在內(nèi)部需要自己定義一個 函數(shù) 給返回出去, 并且,可能出現(xiàn) 返回新函數(shù)調(diào)用時 繼續(xù)傳入?yún)?shù) 所以我們需要將參數(shù)合并
Function.prototype.mybind = function (thisArgs, ...argArray) { const oldFunc = this console.log(this); thisArgs = (thisArgs !== undefined && thisArgs !== null) ? Object(thisArgs) : window function proxyFn(...args) { thisArgs.func = oldFunc const funcCallResult = thisArgs.func([...argArray, ...args]) // 合并兩次的 參數(shù) delete thisArgs.func return funcCallResult } return proxyFn }
謝謝,到此就完成了簡單版的 call apply bind 的實(shí)現(xiàn),更多關(guān)于JS call apply bind方法的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
js實(shí)現(xiàn)兔年轉(zhuǎn)圈圈動畫示例
這篇文章主要為大家介紹了js實(shí)現(xiàn)兔年轉(zhuǎn)圈圈動畫示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01Web?Components實(shí)現(xiàn)類Element?UI中的Card卡片
這篇文章主要為大家介紹了Web?Components實(shí)現(xiàn)類Element?UI中的Card卡片實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07微信小程序技巧之show內(nèi)容展示,上傳文件編碼問題
這篇文章主要介紹了微信小程序技巧之show內(nèi)容展示,上傳文件編碼問題,具有一定的參考價值,有興趣的可以了解一下。2017-01-01微信小程序網(wǎng)絡(luò)請求wx.request詳解及實(shí)例
這篇文章主要介紹了微信小程序網(wǎng)絡(luò)請求wx.request詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-05-05微信小程序 (三)tabBar底部導(dǎo)航詳細(xì)介紹
這篇文章主要介紹了微信小程序 (三)tabBar底部導(dǎo)航詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下2016-09-09微信小程序使用navigateTo數(shù)據(jù)傳遞的實(shí)例
這篇文章主要介紹了微信小程序使用navigateTo數(shù)據(jù)傳遞的實(shí)例的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下2017-09-09