unction foo() {
console.log(this)
}
foo()//window
var arr1=[]
foo.call(arr1))//[]
// call原理
Function.prototype.myCall=function (target) { //形參就相當于 var target=undefined
/*
實現原理:把目標函數foo綁定在目標對象target上(本來函數的this指向window,但是想要讓this指向我們指定的對象,所以有下面這些操作)
1. 獲取目標對象
2. 獲取目標函數 foo,并把目標函數foo綁定到目標對象上
3. 執行目標函數并返回
*/
//如果傳參則使用Object()包裹一下,有可能不是一個對象,若沒有傳參默認為window
target=target ? Object(target) : window
//將targetFunction綁定到target上,targetFunction是定義的臨時屬性
target.targetFunction=this
//獲取傳入的除了target以外剩余的參數
let args=[...arguments].slice(1)
let result=target.targetFunction(...args)
//刪除臨時屬性
delete target.targetFunction
return result
}
var arr1=[]
foo.myCall(arr1))//arr1 []
注意:target.targetFunction=this這行代碼的意思就是把foo.call(arr1) 中的foo函數掛載到arr1上。當執行foo.myCall() 時, myCall里的 this 指向調用者foo,所以這里的this就是foo函數。
javascript調用一個函數有兩種方法,
(1)直接使用函數名以及對應的參數
(2)使用call進行調用
定義一個函數
/**
* 兩數相加得到結果
* @param {double} x
* @param {double} y
* @returns 相加結果
*/
function CalNum(x,y){
return x+y;
}
// 正常調用函數
var x=1, y=2;
var ret=CalNum(x,y);
console.log("正常調用的結果是:" + ret);
結果是:
正常調用結果是:3
//使用call調用當前的函數
var obj={
name:"x"
}
var ret2=CalNum.call(obj,x,y);
console.log("采用call調用的結果是:" + ret2);
注意:使用call調用的時候。funcion中的this將變成obj而不是function本身的this.
或者使用空對象來進行
var ret2=CalNum.call({},x,y);
最終的結果是
采用call調用的結果是:3
使用call的核心是是改變function的this指向問題,不再是指向本身,而是指向傳入的對象。
文分享自華為云社區《關于 JavaScript 中 call 方法的實現,附帶詳細解析!-云社區-華為云》,作者:CoderBin。
本文將全面的,詳細解析call方法的實現原理,并手寫出自己的call方法,相信看完本文的小伙伴都能從中有所收獲。
創作不易,你們的點贊收藏留言就是我最大的動力
如果文中有不對、疑惑的地方,歡迎各位小伙伴們在評論區留言指正
調用函數,可傳入參數,改變this指向
1. 邊界判斷
2. 將調用的函數設置為對象(傳入的context)的方法(改變this指向)
3. 調用函數,得到返回值,并返回
/**
* !實現 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
}
// 測試
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方法的功能
通過在傳入的對象上,臨時新增一個方法,這個方法的值是當前 binCall 的調用者。然后 context.fn(...argArray) 調用這個函數,通過隱式綁定的方式改變了 this 的指向,最后得到結果并返回
點擊下方,第一時間了解華為云新鮮技術~
華為云博客_大數據博客_AI博客_云計算博客_開發者中心-華為云
*請認真填寫需求信息,我們會在24小時內與您取得聯系。