this 指向总结
this 关键字是一个非常重要的语法点。
this 可以用在构造函数之中,表示实例对象。除此之外,this 还可以用在别的场合。但不管是什么场合,this 都有一个共同点:它总是返回一个对象。
关于 this 的指向,有一种广为流传的说法就是“谁调用它,this 就指向谁”。
这样的说法没有太大的问题,但是并不全面。总结起来,this 的指向规律有如下几条:
-
在函数体中,非显式或隐式地简单调用函数时,在严格模式下,函数内的 this 会被绑定到 undefined 上,在非严格模式下则会被绑定到全局对象 window/global 上。
-
一般使用 new 方法调用构造函数时,构造函数内的 this 会被绑定到新创建的对象上。
-
一般通过 call/apply/bind 方法显式调用函数时,函数体内的 this 会被绑定到指定参数的对象上。
-
一般通过上下文对象调用函数时,函数体内的 this 会被绑定到该对象上。
-
在箭头函数中,this 的指向是由外层(函数或全局)作用域来决定的。
当然,真实环境多种多样,具体问题还要具体分析。
全局环境中的 this
例题 1:
function f1() {
console.log(this);
}
function f2() {
'use strict'
console.log(this);
}
f1(); // window or global
f2(); // undefined
这种情况相对简单、直接,函数在浏览器全局环境下被简单调用,在非严格模式下 this 指向 window,在通过 use strict 指明严格模式的情况下指向 undefined。
例题 2:
const foo = {
bar : 10,
fn : function(){
console.log(this); // window or global
console.log(this.bar); // undefined
}
}
var fn1 = foo.fn;
fn1();
这里的 this 仍然指向 window。虽然 fn 函数在 foo 对象中作为该对象的一个方法,但是在赋值给 fn1 之后,fn1 仍然是在 window 的全局环境下执行的。因此上面的代码仍然会输出 window 和 undefined。
上下文对象调用中的 this
例题 3:
const foo = {
bar : 10,
fn : function(){
console.log(this); // { bar: 10, fn: [Function: fn] }
console.log(this.bar); // 10
}
}
foo.fn();
这时,this 指向的是最后调用它的对象,在 foo.fn( ) 语句中,this 指向的是 foo 对象。
例题 4:
const student = {
name: 'zhangsan',
fn: function () {
return this;
}
}
console.log(student.fn() === student); // true
在上面的代码中,this 指向当前的对象 student,所以最终会返回 true。
this 指向绑定事件的元素
DOM 元素绑定事件时,事件处理函数里面的 this 指向绑定了事件的元素。
这个地方一定要注意它和 target 的区别,target 是指向触发事件的元素。
示例:
<ul id="color-list">
<li>red</li>
<li>yellow</li>
<li>blue</li>
<li>green</li>
<li>black</li>
<li>white</li>
</ul>
// this 是绑定事件的元素
// target 是触发事件的元素 和 srcElememnt 等价
let colorList = document.getElementById("color-list");
colorList.addEventListener("click", function (event) {
console.log('this:', this);
console.log('target:', event.target);
console.log('srcElement:', event.srcElement);
})
当我点击如下位置时打印出来的信息如下: