關於JS中this的問題
JS中的函數調用有4種方式:
1、作爲普通函數調用
2、作爲對象方法調用
3、作爲構造函數調用
4、使用call或者apply
全局執行:
首先,我們嘗試全局執行下console.log(this);
瀏覽器會輸出window對象
注意,如果在嚴格模式下執行'use strict',則輸出的會是undefined
第一種情況:作爲普通函數調用
function a(){
this.name = '張三';
console.log(this.name);
console.log(this);
}
a();
console.log(name);
//張三
//window
//張三
//這裏的this指向的是全局window對象,name爲定義的全局變量
//換一種寫法
var name = '張三';
function a(){
var name = '李四';
console.log(this.name);
}
a();
//張三
//同樣,這裏的this.name指向的也是全局對象name
//再換一種寫法
var name = '張三';
function a(){
this.name = '李四';
}
a();
console.log(name);
//李四
第二種情況:作爲對象方法調用
var name = '張三';
var person = {
name : '李四',
showName : function(){
console.log(this.name);
}
}
person.showName();
//李四
//這裏this指向的是person
//再執行兩句話
var other = person.showName;
other();
//張三
//這裏other屬於全局對象,等同於window.other,this是在執行時綁定它的作用域,所以這裏的this表示window對象
//注意setTimeout的一些坑
var person = {
fun1 : function(){
console.log(this);
},
fun2 : function(){
setTimeout(this.fun1, 1000);
}
}
person.fun2();
//在這種情況下,會輸出window對象
//可以理解爲setTimeout本身也是一個函數,等同於window.setTimeout,因此,這裏的this是在執行的時候綁定它的作用域,則爲window
//解決辦法
var person = {
fun1 : function(){
console.log(this);
},
fun2 : function(){
var _this = this;
setTimeout(function(){
console.log(this);
console.log(_this);
}, 1000);
}
}
//window
//person
person.fun2();
//通過定義一個_this來存儲this的指向
第三種情況:作爲構造函數調用
function Person(){
this.name = '張三';
}
var a = new Person();
console.log(a.name);
//張三
//使用new關鍵字生成的對象,會將構造函數中的this作用域綁定在該對象上面
第四種情況:使用call或者apply
var a = {
name : '張三'
}
function foo(){
console.log(this);
}
foo.call(a);
//Object{name : '張三'}
//在執行foo.call(a)的時候,函數內部的this指向了a這個對象