摘要:本文将全面的,詳細解析call方法的實作原理
本文分享自華為雲社群《關于 JavaScript 中 call 方法的實作,附帶詳細解析!》,作者:CoderBin。
本文将全面的,詳細解析call方法的實作原理,并手寫出自己的call方法,相信看完本文的小夥伴都能從中有所收獲。
call 方法的實作
1.函數作用
調用函數,可傳入參數,改變this指向
2.總體步驟
- 邊界判斷(this,context)
- 将調用的函數設定為對象(傳入的context)的方法(改變this指向)
- 調用函數,得到傳回值,并傳回
3. 詳細步驟
1. 邊界判斷
- 判斷目前 this 是否為一個函數,否則傳回錯誤消息
- 判斷傳入的 context 參數是否存在,存在則使用 Object() 轉換為對象賦給 context,否則将 window 指派給 context
2. 将調用的函數設定為對象(傳入的context)的方法(改變this指向)
3. 調用函數,得到傳回值,并傳回
- 調用函數,得到結果
- 删除 context 身上的 fn 函數
- 傳回結果
4. 代碼實作
/**
* !實作 binCall() 方法
* @param {*} context 綁定的對象
* @param {...any} args 剩餘參數
* @returns
*/
Function.prototype.binCall = function(context, ...args) {
if (typeof this !== 'function') console.error('type Error'); // 1
context = (context!==null && context!==undefined) ? Object(context) : window
context.fn = this // 2
const result = context.fn(...args) // 3
delete context.fn;
return result
}
5. 測試代碼
// 測試
function sum(num1, num2) {
console.log('sum 被執行', this);
return num1 + num2
}
// 原生的 call() 方法
console.log(sum.call({name: 'bin'},1,2));
// 自定義的 binCall() 方法
console.log(sum.binCall({name: 'bin'},1,2));
經過原生的call方法和手寫的binCall方法測試,我們手動實作的binCall方法也能實作原生call方法的功能
6. 細節解析
- this 指向的就是調用 binCall() 的那個函數(隐式綁定);
- 傳入的 context 參數表示:将 this 的指向改為這個參數;
- 改變 this 指向其實就是在 context 上添加一個臨時的方法,值為 this;
- 調用 context.fn() 時,就已經改變了 this 的指向,同時得使用展開運算符傳入參數
- delete context.fn 删除那個臨時方法是因為已經不需要用了