this
this
總是指向一個對象,而具體指向的哪一個對象友驮,是基于函數(shù)的執(zhí)行環(huán)境動態(tài)綁定的漂羊,而非函數(shù)被聲明時的環(huán)境。
this 的指向
除去不常見的 with
和eval
的情況卸留,具體到實際的應用中走越,this
的指向可以分為以下四種:
- 作為對象的方法調(diào)用
- 作為普通函數(shù)調(diào)用
- 構(gòu)造器調(diào)用
-
call()
和apply()
動態(tài)綁定
1 作為對象的方法調(diào)用
當函數(shù)作為對象的方法調(diào)用的時候,this
指向該對象艾猜。
var a = 2
var obj = {
a: 1,
getA: function() {
console.log(this.a)
}
}
obj.getA() // 1
var b = obj.getA
b() // 2买喧,執(zhí)行的環(huán)境是 window
2 作為普通函數(shù)調(diào)用
當函數(shù)作為普通函數(shù)調(diào)用的時候,此時的 this
指向全局對象匆赃,也就是JavaScript
中的window
淤毛。
var a = 2
var obj = {
a: 1,
getA: function() {
console.log(this.a)
}
}
var b = obj.getA
b() // 2,執(zhí)行的環(huán)境是 window
3 構(gòu)造器的調(diào)用
除了宿主對象提供的一些內(nèi)置函數(shù)算柳,大部分JavaScript
函數(shù)都可以當作是構(gòu)造器來使用低淡,構(gòu)造器的外表和普通函數(shù)一模一樣,他們的區(qū)別在于被調(diào)用的方式瞬项。
當用new
運算父調(diào)用函數(shù)的時候蔗蹋,該函數(shù)總會返回一個對象,通常情況下囱淋,構(gòu)造器里的 this
就指向返回的這個對象猪杭。
var MyClass = function() {
this.name = 'yy'
}
var obj = new MyClass()
console.log(obj.name) // yy
使用
new
來調(diào)用函數(shù),或者說發(fā)生構(gòu)造函數(shù)調(diào)用時妥衣,會自動執(zhí)行下面的操作皂吮。
- 創(chuàng)建(或者說構(gòu)造)一個全新的對象戒傻。
- 這個新對象會被執(zhí)行
[[ 原型 ]]
連接。 - 這個新對象會綁定到函數(shù)調(diào)用的
this
蜂筹。 - 如果函數(shù)沒有返回其他對象需纳,那么
new
表達式中的函數(shù)調(diào)用會自動返回這個新對象。
4 apply() 和 call()
和普通的函數(shù)調(diào)用相比艺挪,用 Function.prototype.call
和 Function.prototype.apply
可以動態(tài)的改變傳入函數(shù)的 this
不翩。
var obj1 = {
name: 'yy1',
getName: function() {
console.log(this.name)
}
}
var obj2 = {
name: 'yy2'
}
obj1.getName.call(obj2) // yy2
嚴格模式
雖然this
的綁定規(guī)則完全取決于調(diào)用位置,但是只有foo()
運行在非strict mode
下時麻裳,默認綁定才能綁定到全局對象口蝠;如果使用嚴格模式(strict mode
),那么全局對象將無法使用默認綁定津坑,因此this
會綁定到 undefined
亚皂。
function foo() {
"use strict";
console.log( this.a );
}
var a = 2;
foo(); // TypeError: this is undefined
call
function.call(obj[,arg1[, arg2[, [,.argN]]]]])
- 調(diào)用
call
的對象必須是個函數(shù)function
; -
call
的第一個參數(shù)將會是function
改變上下文后指向的對象国瓮,如果不傳,將會默認是全局對象window
狞谱; - 第二個參數(shù)開始可以接收任意個參數(shù)乃摹,這些參數(shù)將會作為
function
的參數(shù)傳入function
; - 調(diào)用
call
的方法會立即執(zhí)行跟衅。
apply
function.apply(obj[,argArray])
- 與
call
方法的使用基本一致孵睬,但是只接收兩個參數(shù),其中第二個參數(shù)必須是一個數(shù)組或者類數(shù)組伶跷,這也是這兩個方法很重要的一個區(qū)別掰读; - 第二個參數(shù)接收數(shù)組或者類數(shù)組,但是都會被轉(zhuǎn)換成
類數(shù)組
傳入func
中叭莫,并且會被映射到func
對應的參數(shù)上蹈集。
apply 的用法
具體應用體現(xiàn)在將數(shù)組映射為對應的參數(shù)。
// 求數(shù)組中最大項
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
var max = Math.max.apply(null, arr)
// 合并兩個數(shù)組并且返回新數(shù)組的長度
var arr1 = [1, 2, 3]
var arr2 = [4, 5, 6]
alert(Array.prototype.push.apply(arr1, arr2))