詳解JS中 call 方法的實現
摘要: 本文將全面的,詳細解析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 刪除那個臨時方法是因為已經不需要用了
7. 核心原理
通過在傳入的對象上,臨時新增一個方法,這個方法的值是當前 binCall 的調用者。然後 context.fn(...argArray) 調用這個函數,通過隱式綁定的方式改變了 this 的指向,最後得到結果並返回。
「其他文章」
- 線程池底層原理詳解與源碼分析
- 30分鐘掌握 Webpack
- 線性迴歸大結局(嶺(Ridge)、 Lasso迴歸原理、公式推導),你想要的這裏都有
- 【前端必會】webpack loader 到底是什麼
- 中心化決議管理——雲端分析
- HashMap底層原理及jdk1.8源碼解讀
- 詳解JS中 call 方法的實現
- 打印 Logger 日誌時,需不需要再封裝一下工具類?
- 初識設計模式 - 代理模式
- 密碼學奇妙之旅、01 CFB密文反饋模式、AES標準、Golang代碼
- Springboot之 Mybatis 多數據源實現
- CAS核心思想、底層實現
- 面試突擊86:SpringBoot 事務不回滾?怎麼解決?
- 基於electron vue element構建項目模板之【打包篇】
- MiniWord .NET Word模板引擎,藉由Word模板和數據簡單、快速生成文件。
- 認識線程,初始併發
- 1-VSCode搭建GD32開發環境
- 初識設計模式 - 原型模式
- 線程安全問題的產生條件、解決方式
- 2>&1到底是什麼意思?