javascript call方法的用處及原理

call的做用

一句話:改變調用方法的this指向,示例以下:bash

function a(){
	console.log(this);
}
a();
a.call({name:"西瓜"});
複製代碼

能夠看到,第一次this指向了window,第二次this指向了傳入的對象;app

那麼在執行call方法的時候,內部作了什麼處理呢?

先來看一個東西,或許就能明白函數

var a = {
	name:"西瓜",
	run:function(){
		console.log(this);
		console.log(this.name);
	}
}
a.run();
複製代碼

上面這段代碼,相信小夥伴都能看懂,其實,call執行的時候,也是作了這樣的處理;。學習

手動來實現一個call

Function.prototype.MyCall = function(obj){
	var newObj = obj || window;
	newObj.fn = this;
	var params = [...arguments].slice(1);
	var result = newObj.fn(...params);
	delete newObj.fn;
	return result;
}
複製代碼

就上面的這段代碼,就實現了一個call的功能,來看下這段代碼都作了哪些事情ui

  1. 定義一個新的對象,若傳入的obj存在,則新對象等於obj,若obj不存在,則等於window
  2. 把this掛在到當前定義的新對象上(this即爲調用的函數);
  3. 第4行代碼處理了函數的傳參;
  4. 而後執行建立的新對象的fn函數(即爲要調用的函數);
  5. 最後在執行了之後,把這個掛載的fn刪除;

來驗證一下是否正確this

function test(){
	console.log(this);
}
test();
test.MyCall({name:"西瓜"});
複製代碼

結果以下圖: spa

能夠看到,結果和使用call的時候輸出的一致。這樣就本身手動實現了一個call方法;

接下來,講一個我在學習call的時候,網上常常講到的一個案例,咱們一塊兒來看一下:

function f1(a){
	console.log(1);
	console.log(this);
}
function f2(){
	console.log(2);
	console.log(this);
}

f1.call(f2);
f1.call.call(f2);
複製代碼

想一下,這段代碼打印出來的會是一個什麼結果呢? prototype

f1.call(f2)的打印結果,相信你們都能理解,這裏就不解釋了;重點來說一下 f1.call.call(f2); 首先,咱們用剛剛本身實現的call方法來試試,會不會出現一樣的結果;

f1.MyCall(f2);
f1.MyCall.MyCall(f2);
複製代碼

結果固然是同樣的啦!以下: code

爲何會這樣呢,來談談我對這個結果的理解吧(可能其餘小夥伴有更好的理解)! 把上面本身實現的call方法複製下來

Function.prototype.MyCall = function(obj){
    var newObj = obj || window;
	newObj.fn = this;
	var params = [...arguments].slice(1);
	var result = newObj.fn(...params);
	delete newObj.fn;
	return result;
}
複製代碼

當咱們執行f1.MyCall.MyCall(f2)的時候,上面這個MyCall方法中的thisnewObj指的分別是什麼? 個人理解是thisf1.MyCall,即爲Function.prototype.MyCallnewObjf2方法; 所當f1.MyCall.MyCall(f2)執行的時候,結果就變了如下結果:cdn

var newObj = f2;
f2.fn = Function.prototype.MyCall;
複製代碼

接下來MyCall的第5行是否是會執行newObj.fn? 其實就是執行f2.MyCall()這個結果你們應該都知道了吧;

若是說上面這個理解了,能夠想一想下面幾個會打印出什麼內容:

f1.call.call.call(f2)
f1.call.call.call.call(f2)
f1.call.call.call.call.call(f2)
複製代碼

其實都是同樣的哈!

結尾

除了call,還有兩個相似的方法apply,bind,這裏就不作過多的解釋了,相信小夥伴必定也能跟着這樣的思路去手寫出來。有什麼問題就給我留言吧!

相關文章
相關標籤/搜索