一說到call,
————總是call
、‘張三’、‘李四’的區別什麼什麼的,說的很清楚,轉身還是傻傻分不清楚他們的區別了,相似的事情總是喜歡一起來說,這對於新手來說總是容易混亂的,今天就來理解下call的用法;
通俗點:
call
的作用就是: 改變函式執行時的上下文 也就是this
的指向;
用法:
Food.call(thisArg, arg1, arg2, ...)複製程式碼
來看個例子 --- A
function fun(){
this.name = 'fun-name'
this.age = 'fun-age'
}
var wrap = {
age: 'default',
name: 'default',
myfun: function() {
fun()
}
}
wrap.myfun();
console.log(wrap.age) // 'default-age'
console.log(window.age) // 'fun-age'複製程式碼
直接執行這個函式 wrap.myfun();
執行這個函式後
1、在wrap
下面執行myfun()
後,其中的this
指向window
全域性的
2、在window
全域性下面建立了一個age
屬性,值為'fun-age'
3、wrap
中的age
還是default
來看個例子 --- B
function fun(){
this.name = 'fun-name'
this.age = 'fun-age'
}
var wrap = {
age: 'default',
name: 'default',
obj: function() {
fun.call(this) // **---注意這裡打 call 了---**
}
}
wrap.myfun();
console.log(wrap.age) // 'fun-age' --發生了變化---
console.log(window.age) // 'age is not defined' --發生了變化---複製程式碼
例子B執行時:
wrap.obj()
執行後,在執行fun
時,把this
, call進去了, 這個this
是指向wrap
,所以fun
執行時其中的this
指向的是wrap
,自然改變的就是wrap
中的age
,這就是call
的作用改變了fun
執行時的上下文;
好累,反正我是大概懂了他(this)剛才幹了什麼;
那麼在我們的coding中,一般什麼時候用到call了?
1、利用call來 做繼承
var Person = function () {
this.fun = function() {
console.log('longlee') }
};
var student = function () {
Person.call(this);
};
var st = new student ();
g1.fun() // 輸出: longlee複製程式碼
如果不在student函式中執行 call,new出來的例項是沒有fun屬性方法的;打call就可以實現繼承Person方法了;
2、判斷資料的型別 【object、 array、 null】
var obj1 = {name: 'longlee'}
var obj2 = ['longlee']
var obj3 = null
Object.prototype.toString.call(obj1) // "[object Object]"
Object.prototype.toString.call(obj2) // "[object Array]"
Object.prototype.toString.call(obj3) // "[object Null]"
Object.prototype.toString.call(12) // "[object Number]"
....
....複製程式碼
3、類(偽)陣列使用陣列方法
var arg = Array.prototype.slice.call(arguments);
arguments是函式接收的實際引數個數,他是一個偽陣列,不具有陣列的一般方法。比如 push、pop...,
但是我們能通過 Array.prototype.slice.call 轉換為真正的陣列
這樣 arguments 就可以應用 Array 下的所有方法了。複製程式碼
4、獲取陣列中的最大值和最小值
maxInNumbers = Math.max.call(Math, 55, 888 , 521 , -36); // 888
number 本身沒有 max 方法,但是 Math 有,我們就可以藉助 call 使用其方法。複製程式碼
就說到這了,再說下去,我自己也快消化不良了、、、、
題外話:
說到陣列的最大值、最小值。我控制不住自己了,一個ES6的簡潔方法Math.max(...[2,1,3])
// 3Math.min(...[2,1,3])
// 1
個人見解,有誤之處,大神請指出,以免改正!
弄懂 call 了。可以繼續打 call 了