call方法的作用:
var obj={name:"張三"};
function fn(){
console.log(this);
}
fn.call(obj);
首先讓原型上的call方法執行,在執行call方法的時候,讓fn方法中的this變為第一個參數obj,然后再把fn這個函數執行
模擬一個內置call方法,探究原理:
Function.prototype.myCall=function(context){
//---->myCall方法中的this是當前要操作和改變其this關鍵字的那個函數名(即fn)
//步驟1:讓this這個函數中的“this關鍵字”變為context(也就是讓fn中的this關鍵字變為context的值----->即obj)
var that=eval(this.toString().replace("this","obj"));
//先把this函數中的代碼變為字符串,然后把this函數中的“this關鍵字”替換為“obj”,最后用eval()把字符串變為JS可執行的代碼
//步驟2:讓fn方法執行
this();
};
fn.myCall(obj); //myCall方法中的this是fn
比較:
function fn1(){console.log(1);} function fn2(){console.log(2);}
1、fn1.call(fn2)
//首先fn1通過原型鏈機制找到Function.prototype上的call方法,并且讓call方法執行--->此時call方法中的this是要操作的fn1---->在call方法執行過程中首先讓fn1中的“this關鍵字”變為fn2,然后再讓這個fn1執行
2、fn1.call.call(fn2); //---->2
//首先fn1通過原型鏈找到Function.prototype上的call方法,然后再讓call方法通過原型再找到Function原型上的call(因為call本身的值是一個函數,所以同樣可以找到Function.prototype)--->在第二次找到call的時候讓方法執行,方法中的this是fn1.call(即變為fn1.call();也就相當于是call函數本身),---->讓這個方法中的this變為fn2,然后再讓fn1.call執行(也就相當于把call函數中的this變為fn2,也就是執行fn2)---->最后結果為2
3、fn1.call.call.call.call.call(fn2);最終執行的是fn2
——————————————————————————————————————————
fn.call(obj):讓fn方法中的this變為第一個參數obj
var obj={name:"張三“};
function fn(num1,num2){
consloe.log(num1+num2);
console.log(this);
}
fn(100,200); //this--->window;num1=100,num2=200--->300
fn.call(100,200); //this--->100,num1=200,num2=undefined---->undefined
fn.call(obj,100,200); //this-->obj,num1=100,num2=200;
fn.call(); //this--->window;在嚴格模式下(”use strict“)this--->undefined
fn.call(null); //this--->window;在嚴格模式下(”use strict“)this--->null
fn.call(undefined); //this--->window;在嚴格模式下(”use strict“)this--->undefined