目前為止店雅,重名現(xiàn)象很嚴重啊。北京有個老王贞铣,上海也有個老王闹啦,雖然他們都叫老王,但卻是兩個不同的人辕坝,誰又知道哪個才是專門給鄰居送驚喜的老王呢窍奋。
今天不研究老王,只是說說 this 關(guān)鍵字酱畅,看看它到底是誰费变。
一、this 關(guān)鍵字
this 就是指代一個對象圣贸。
隨著 this 所在區(qū)域的不同(函數(shù)使用場景的不同),this 所指代的對象也就不同扛稽,那么 this 在該區(qū)域(場景)的值會發(fā)生變化吁峻。
this 是誰,取決于函數(shù)的調(diào)用方式在张,那么 this 指代的對象就是:調(diào)用函數(shù)的那個對象用含。
二、使用場景
1. 純粹的函數(shù)調(diào)用
不論函數(shù)是否嵌套帮匾,只要是在全局作用域下運行啄骇,this 全部指代 window 對象。
- 全局作用域下:this 指代的就是 window 對象
此時相當于在 window 對象上綁定了函數(shù) fn瘟斜,調(diào)用形式相當于window.fn()
function fn() {
console.log(this);
}
fn()
- 內(nèi)部函數(shù)(函數(shù)嵌套產(chǎn)生):this 指代的仍是 window 對象缸夹。
function outerFn () {
function fn(){
console.log(this);
}
fn()
}
outerFn()
- 定時器內(nèi):this 指代的是 window 對象
document.addEventListener('click', function(e){
setTimeout(function(){
console.log(this);
}, 200);
});
2. DOM對象綁定事件
- 此時 this 指代的是綁定事件的那個元素
document.addEventListener('click', function(e){
console.log(this);
});
3. 作為構(gòu)造函數(shù)調(diào)用
- 構(gòu)造函數(shù)內(nèi)痪寻,this 指代的就是實例對象
function City(name){
this.name = name;
}
City.prototype.say = function(){
console.log(this.name);
}
var first = new City('北京');
first.say(); // 北京
構(gòu)造函數(shù),就是專門用來生成“對象”的函數(shù)虽惭。構(gòu)造函數(shù)作為模板橡类,配合 new 操作符生成一個新的實例對象。此時 this 指代的就是這個新的實例對象芽唇。
4. 作為對象方法調(diào)用
- 函數(shù)在對象內(nèi)作為方法時顾画,this 指代的就是該對象
var city = {
name: '北京',
say: function(){
console.log(this);
}
}
city.say(); // Object {name: "北京"}
函數(shù)可以作為一個對象的屬性,此時該函數(shù)被稱為該對象的方法匆笤。
三研侣、this 的綁定
1. Function.prototype.call()
簡單來說,call 方法的作用就是炮捧,以指定的 this 值和參數(shù)值去調(diào)用某個函數(shù)庶诡。
call 方法接收參數(shù)為一個參數(shù)列表。第一個參數(shù)就是:希望指定的 this 的值寓盗。
如果該參數(shù)的值為 null 或 undefined灌砖,則表示不需要傳入任何參數(shù)。
語法:fn.call(thisValue, [param1, param2...])
var city= {
name: '北京'
}
function say(){
return this;
}
say.call(city); // Object {name: "北京"}
還可以這樣
var maxValue= Math.max.call(null, 6,3,9,2,1);
console.log(maxValue); // 9
2. Function.prototype.apply()
apply 方法與 call 方法類似傀蚌。
它倆的區(qū)別就是基显,接收的參數(shù)不同,apply 方法接收的參數(shù)為一個參數(shù)數(shù)組善炫。
語法:fn.apply(thisValue, [paramArray])
var city= ['北京', '上海', '天津']
function say(){
return this;
}
say.apply(city); // ["北京", "上海", "天津"]
還可以這樣
var arr = [6,3,9,2,1];
var maxValue= Math.max.apply(null, arr);
var index = [].indexOf.apply(arr, [maxValue])
console.log(maxValue, index); // 9 2
3. Function.prototype.bind()
bind 方法與 call 方法和 apply 方法也是類似的。
但 call 和 apply 帶有借用的意思箩艺,也就是也用某個函數(shù)或方法窜醉,處理自己的參數(shù)。
而 bind 方法艺谆,卻會創(chuàng)建一個新函數(shù)榨惰,以指定的 this 值和參數(shù)值,去調(diào)用這個新函數(shù)静汤。
同樣會將傳入的第一個參數(shù)作為指定的 this 值琅催。
語法:fn.bind(thisValue[, arg1[, arg2[, ...]]])
var obj1 = {
name: '小明',
fn: function(){
console.log(this.name)
}
}
var obj2 = {
name: '大剛'
}
var say = obj1.fn.bind(obj2); // bind 綁定 this
say(); // 大剛
------
var print = obj1.fn; // 直接賦值給 print
print(); // window
------
var print = obj1.fn.bind(obj1); // 直接賦值給 print
print(); // 小明
來個小測驗
var city= {
name: '北京',
say: function(){
console.log(this);
}
}
以下情況 this 分別代表誰?
city.say(); // city
------
var fn = city.say;
fn(); // window
------
(city.say = city.say)(); // window