最近小弟在網上看到一道面試題,題目雖然簡單,但包含的知識點較多,有利於對 JavaScript 作用域,this 指向,call/apply,箭頭函式的理解。在這裡跟大家分享總結一下。 題目先睹為快
var a = 10
var obj = {
a: 20,
say: function() {
console.log(this.a)
}
}
obj.say()
複製程式碼
很明顯答案是輸出 20,這裡的 this 指向的是 obj。obj.a=20。
但是如何才能列印出 10 呢?有如下方法
1.箭頭函式
箭頭函式不繫結 this,會捕獲其所在的上下文的 this 值,作為自己的 this 值。我們可以利用這一點進行修改。這樣 this 的指向就是 window。
var a = 10
var obj = {
a: 20,
say: () => {
console.log(this.a)
}
}
obj.say() // -> 10
複製程式碼
下面說下箭頭函式和普通函式的區別
- 箭頭函式是匿名函式,不能作為建構函式,不能使用 new
- 箭頭函式不繫結 arguments,取而代之用 rest 引數…解決
- 箭頭函式不繫結 this,會捕獲其所在的上下文的 this 值,作為自己的 this 值
- 箭頭函式通過 call() 或 apply() 方法呼叫一個函式時,只傳入了一個引數,對 this 並沒有影響。
- 箭頭函式沒有原型屬性
- 箭頭函式不能當做 Generator 函式,不能使用 yield 關鍵字
2、改變 this 的指向
在 javascript 中,call 和 apply 都是為了改變某個函式執行時的上下文(context)而存在的,換句話說,就是為了改變函式體內部 this 的指向。下面使用 call 改變 this 指向的方法
var a = 10
var obj = {
a: 20,
say: function() {
console.log(this.a)
}
}
obj.say.call(this) // 此處顯示繫結this為全域性window物件
複製程式碼
下面說一下 call,apply 的區別 對於 apply、call 二者而言,作用完全一樣,只是接受引數的方式不太一樣。call 接受的是一個字串,而 apply 接受的是一個陣列
func.call(this, arg1, arg2)
func.apply(this, [arg1, arg2])
複製程式碼
常見應用
// 獲取陣列中的最大值和最小值
var numbers = [5, 458 , 120 , -215 ];
var maxInNumbers = Math.max.apply(Math, numbers), //458
var maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458
// 陣列追加
var array1 = [12 , "foo" , {name:"Joe"} , -2458];
var array2 = ["Doe" , 555 , 100];
Array.prototype.push.apply(array1, array2);
// array1 值為 [12 , "foo" , {name:"Joe"} , -2458 , "Doe" , 555 , 100]
// 驗證是否是陣列
functionisArray(obj){
return Object.prototype.toString.call(obj) === '[object Array]'
}
複製程式碼
3.建立臨時變數存放函式
var a = 10
var obj = {
a: 20,
say: function() {
console.log(this.a)
}
}
var say = obj.say // 此處先建立一個臨時變數存放函式定義,然後單獨呼叫
say()
複製程式碼