一、this的指向问题
this作为JavaScript中的一个关键字,它的复杂度很高,主要原因是它所处不同场景的代表的指向是不一样的。非严格模式下this指向默认是window,严格模式下默认是undefined
二、this指向实例场景
- 全局环境
- 普通函数调用
- 由
call/apply
函数调用 - 对象属性方法调用
- 构造函数调用
- 箭头函数
- 事件绑定中的this
2-1 全局环境
在全局环境中无论是否是严格模式,this
均指向全局对象,window
// 在浏览器中, window 对象同时也是全局对象:
console.log(this === window); // true
a = 37;
console.log(window.a); // 37
this.b = "MDN";
console.log(window.b) // "MDN"
console.log(b) // "MDN"
2-2 普通函数调用
当普通的函数,直接调用的时候,一般来说分两种情况:
- 严格模式绑定到
undefined
- 非严格模式绑定到全局对象
window
function fun(){
console.log(this);
}
function bar(){
"use strict";
console.log(this);
}
fun() // window
bar() // undefined
2-3 call
,apply
调用的this
call和apply函数可以改变普通函数的this指向,但是不能改变箭头函数的this指向。
var o = {
name: 'andy'
}
function fun(a, b) {
console.log(this);
console.log(a + b);
};
fun.call(o, 1, 2);
var o = {
name: 'andy'
};
function fun(arr) {
console.log(this);
console.log(arr); // 'pink'
};
fun.apply(o, ['pink']);
2-4 对象属性方法调用
作为对象属性方法调用,都指向前面调用函数的那个对象。
var student = {
name: "tom",
fn: function () {
return this;
},
};
console.log(student.fn() === student); //true
2-5 构造函数中的this
function Person(name) {
this.name = name
}
var p1 = new Person('tom')
console.log(p1.name); //tom
在构造函数中,this经过new的调用发生了改变,在使用new调用时:
1.new会在内存中新创建一个空对象,且实例化
2.new会让this指向这个新对象
3.new给这个新对象复制属性和方法
4.return这个新对象
2-6 箭头函数中的this
箭头函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
var obj = {
name: "tom",
fun() {
setTimeout(() => {
console.log(this);
}, 1000);
},
};
obj.fun() // obj
2-7 事件绑定中的this
事件源.onclik = function(){ } //this -> 事件源
事件源.addEventListener(function(){ }) //this->事件源
var div = document.querySelector("div");
div.addEventListener('click',function(){
console.log(this); // this -> div
});
div.onclick = function(){
console.log(this); // this -> div
}
三、总结
this
的指向是由上下文环境动态决定的