關於JavaScript中的this指向問題
js中,this在不同情況下指向對象很複雜,分成很多種情況。
this指向window情況
注意:所有this指向window的情況,在嚴格模式下,this值爲undefined
嚴格模式下,apply(),call()第一個參數傳遞什麼,this就指向什麼
1.全局環境下
console.log(this); // window
2.函數獨立調用
function fn() {
console.log(this);
}
fn(); // window
3.函數嵌套獨立調用
var obj = {
func: function () {
function func2() {
console.log(this);
}
func2(); // window
}
}
obj.func();
4.IIFE 自執行函數
function foo() {
console.log(this); // obj
(function () {
console.log(this); // window
})()
}
var obj = {
fn:foo
}
obj.fn();
5.閉包
function wrap() {
console.log(this); // obj
return function () {
console.log(this); // window
}
}
var obj = {
fn:wrap
}
inner = obj.fn();
inner();
隱式綁定
1.隱式綁定
根據調用方法的對象來確定this
function f1() {
console.log(this);
}
var obj = {
f1:f1,
obj2:{
a:1,
f3:function(){
console.log(this);
}
}
}
obj.f1(); // obj
obj.obj2.f3(); // obj2
f1方法的調用對象是obj
f3方法的調用對象是obj2
2.隱式丟失
當用一個新變量接受對象的方法時,this指向也會發生變化
這個fn屬於window方法,故this指向window
var fn = obj.f1;
fn(); // window
3.內置函數
setTimeout(obj.f1,1000); // window
數組方法forEach,Map等this默認指向window,參數二爲設置this指向
var arr = ['apple','banana','orange'];
arr.forEach(function (){
console.log(this); // window
});
arr.forEach(function (){
console.log(this); // arr
},arr);
4.間接調用
var p = {}
p.f1 = obj.f1;
p.f1(); // window
顯示綁定
call(),apply(),bind()第一個方法都可以綁定對象,該對象爲this指向
var obj = {
name:"egon",
age:12
};
var name = "alex";
var age = 20
function fn() {
console.log(this);
console.log(this.name+this.age);
}
fn(); // window alex20
fn.call(obj); // obj egon12 call(this指向,方法參數數組)
fn.apply(obj); // obj egon12 apply(this指向,方法參數1,方法參數2...方法參數n)
f1 = fn.bind(obj);
f1(); // obj egon12
硬綁定
在函數內部的函數已經顯示綁定this指向後,無聊怎麼改變外部函數的this指向,內部函數this指向不變
var obj = {
name:"egon",
age:12
};
var obj2 = {
name:"alex",
age:16
};
var name = "apple";
function f1() {
console.log(this);
console.log(this.name);
}
function fn() {
console.log(this);
f1.call(obj); // 內部函數this始終指向obj
}
fn();
fn.call(obj2);
new新對象時this指向
案例一
function fn() {
console.log(this);
return {
name:'cxk'
}
}
var fn2 = new fn(); // this指向構造函數 fn
console.log(fn2); // 指向return返回的對象 也就是新創建的對象
案例二
var obj = {
a:3,
fav:function(){
console.log(this);
return this;
}
}
var p = new obj.fav(); // this指向構造函數
console.log(p);
// 實例化出來的對象,內部的constructor屬性指向當前的構造函數
console.log(p.constructor === obj.fav); // true