关于JavaScript中this指向问题
js中,this在不同情况下指向对象很复杂,分成很多种情况。
this指向window情况
注意:所有this指向window的情况,在严格模式下,this值为undefined
严格模式下,apply(),call()第一个参数传递什么,this就指向什么
1.全局环境下
全局函数下使用this默认指向window,如果是严格模式,this为undefined
console.log(this); // window
2.函数独立调用
创建在全局作用域下的函数,全局作用域下调用的函数,this指向window
function fn() {
console.log(this);
}
fn(); // window
3.函数嵌套独立调用
当两层函数时,内部函数this指向window
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(); // p对象
显示绑定
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指向
案例一
创建对象前,this指向构造函数;创建对象后,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);
this.a = 1;
return this;
}
}
var p = new obj.fav(); // this指向构造函数 fav{}
console.log(p); // fav{a: 1}
// 实例化出来的对象,内部的constructor属性指向当前的构造函数
console.log(p.constructor === obj.fav); // true