相信很多前端小夥伴們在寫**的時候應該都用過call()
這兩個方法,應該也對這兩個方法有個基本的了解。但肯定也有些小夥伴對它們不是很熟悉,那這次就來**一下這兩個方法
想要深入了解call()
這兩個方法,那麼必須要先知道他們的基本作用:
改變物件的執行上下文
我們在寫乙個方法的時候,總是會用到乙個關鍵字this
,而this
的指向就是我們這裡所說的執行上下文(執行環境)
首先我們要知道,this
指向的永遠是呼叫該方法的物件,如何證明this
的指向就是當前物件呢?看下面這段**:
function
func
() func(); // 1
**中方法執行後控制台輸出1
,由於func
是全域性物件window
下的乙個方法,那麼呼叫該方法的物件就應該是全域性物件window
,所以this
理論上指向的物件就應該是window
如果理論成立,而this.a==1
,也就是說變數a
是乙個全域性變數。在控制台上直接輸入a
或window.a
後回車,會發現輸出了1
,所以在func
這個方法中,this
的指向就是window
換個方式來驗證下:
var
person =
}person.who();
// my name is xiao ming , 18 years old
// true
上面這段**中who
方法是person
物件的乙個屬性,被person
物件呼叫,所以this
的指向也就是person
那麼在知道什麼是執行上下文以後,就可以比較好的理解改變執行上下文的含義了,舉個不恰當的栗子:
我有一張銀行卡,只有我知道密碼,所以只有我取錢,此時銀行卡的「執行上下文」是我;而之後我把密碼告訴了老婆大人,那麼老婆大人知道密碼以後也就可以從這張卡取錢,老婆大人取錢的時候,「執行上下文」就變成了老婆大人
小夥伴們可能就會問了,銀行卡自己用挺好的還能存點私房錢,又為什麼要給老婆大人用呢?
這個問題問得很好,因為我妻管嚴啊 :)你管我呢
簡單來說,方便啊!複雜點說,原因可以有很多,得看具體的業務場景。下面還是舉個
小明有乙個炒菜的鏟子,小明的室友小剛今天突然想自己做菜吃,但是小剛沒有鏟子。小剛又不想為了做個菜單獨買把鏟子,於是就借用了小明的鏟子,這樣既達到了目的,又節省了開支,一舉兩得
改變執行上下文也是一樣,a物件有乙個方法,而b物件因為某種不可言說的情況也需要用到一樣的方法,那麼這時候我們是單獨為b擴充套件個方法呢,還是借用一下a的方法呢?當然是借用a的啦,既完成了需求,又減少了記憶體的占用
在了解異同之前,先來搞清楚這兩個方法都是怎麼用的
call()
function
.call
(obj[,arg1[, arg2[, [,.argn]]]]]
)
function
(obj[,argarray]
)
與call
方法的使用基本一致,但是只接收兩個引數,其中第二個引數必須是乙個陣列或者類陣列,這也是這兩個方法很重要的乙個區別
陣列與類陣列小科普
陣列我們都知道是什麼,它的特徵都有哪些呢?
可以通過角標呼叫,如array[0]
具有長度屬性length
可以通過 for 迴圈和foreach
方法進行遍歷
類陣列顧名思義,具備的特徵應該與陣列基本相同,那麼可以知道,乙個形如下面這個物件的物件就是乙個類陣列
var
arraylike =
類陣列arraylike
可以通過角標進行呼叫,具有length
屬性,同時也可以通過 for 迴圈進行遍歷
我們經常使用的獲取dom節點的方法返回的就是乙個類陣列,在乙個方法中使用arguments
關鍵字獲取到的該方法的所有引數也是乙個類陣列
但是類陣列卻不能通過foreach
進行遍歷,因為foreach
是陣列原型鏈上的方法,類陣列畢竟不是陣列,所以無法使用
那麼如何才能讓類陣列能夠使用foreach
呢?小夥伴們可以在看完本篇後自己思考一下哦
相同點
都能夠改變方法的執行上下文(執行環境),將乙個物件的方法交給另乙個物件來執行,並且是立即執行
不同點
call
方法從第二個引數開始可以接收任意個引數,每個引數會對映到相應位置的func的引數上,可以通過引數名呼叫,但是如果將所有的引數作為陣列傳入,它們會作為乙個整體對映到func對應的第乙個引數上,之後引數都為空
function
func
(a,b,c
) {}
func.call(obj, 1
,2,3
)// function接收到的引數實際上是 1,2,3
func.call(obj, [1
,2,3
])// function接收到的引數實際上是 [1,2,3],undefined,undefined
方法最多只有兩個引數,第二個引數接收陣列或者類陣列,但是都會被轉換成類陣列傳入func中,並且會被對映到func對應的引數上
// function
接收到的引數實際上是 1,2,3
0: 1,
1: 2,
2: 3,
length: 3
})// function
接收到的引數實際上是 1,2,3
跟簡單,根據你要傳入的引數來做選擇,不需要傳參或者只有1個引數的時候,用call
,如果還是單獨的需要逐個傳入的,可以考慮使用call
(如果你不嫌麻煩的話 )
由於可以改變this
的指向,所以也就可以實現物件的繼承
function
superclass
() }function
subclass
() subclass();
// 1
subclass
通過call
方法,繼承了superclass
的print
方法和a
變數
call和apply方法的異同
基本作用 改變物件的執行上下文。this指向執行上下文。執行環境 this指向的永遠是呼叫該方法的物件 function func 中方法執行後控制台輸出1,由於func是全域性物件window下的乙個方法,那麼呼叫該方法的物件就應該是全域性物件window,所以this理論上指向的物件就應該是wi...
call和apply的異同
共同點 作用 呼叫乙個物件的乙個方法,以另乙個物件替換當前物件。將乙個函式的物件上下文從初始的上下文改變為由 thisobj 指定的新物件。如果沒有提供 thisobj 引數,那麼 global 物件被用作 thisobj。以call為例,語法 obj1.method1.call obj2,argu...
call與apply方法的異同
改變物件的執行上下文 什麼是執行上下文?我們在寫乙個方法的時候,總是會用到乙個關鍵字this,而this的指向就是我們這裡所說的執行上下文 執行環境 首先我們要知道,this指向的永遠是呼叫該方法的物件,如何證明this的指向就是當前物件呢?看下面這段 function func func 1 中方...