这是我参与8月更文挑战的第24天,活动详情查看:8月更文挑战
写在前面
在绝大多数情况下,函数的调用方式决定了 this 的值(运行时绑定)。this 不能在执行期间被赋值,并且在每次函数被调用时 this 的值也可能会不同。ES5 引入了 bind 方法来设置函数的 this 值,而不用考虑函数如何被调用的。ES2015 引入了箭头函数,箭头函数不提供自身的 this 绑定(this 的值将保持为闭合词法上下文的值)
var person = {
firstName: "LiMing",
lastName : "Li",
id : 123,
fullName : function() {
return this.firstName + " " + this.lastName;
}
};
this 是什么?
this是当前执行上下文(global、function 或 eval)的一个属性,在非严格模式下,总是指向一个对象,在严格模式下可以是任意值。
JavaScript this 关键词指的是它所属的对象。
它拥有不同的值,具体取决于它的使用位置:
- 在方法中,
this
指的是所有者对象。- 单独的情况下,
this
指的是全局对象。- 在函数中,
this
指的是全局对象。- 在函数中,严格模式下,
this
是undefined。
- 在事件中,
this
指的是接收事件的元素。- 像 call() 和 apply() 这样的方法可以将
this
引用到任何对象。
方法中的 this
在对象方法中,this
指的是此方法的“拥有者”。
在本页最上面的例子中,this
指的是 person
对象。
person
对象是 fullName
方法的拥有者。
fullName : function() {
return this.firstName + " " + this.lastName;
}
单独的 this
在单独使用时,拥有者是全局对象,因此 this 指的是全局对象。
在浏览器窗口中,全局对象是 [object Window]
:
var x = this;
在严格模式中,如果单独使用,那么 this 指的是全局对象 [object Window]
:
"use strict";
var x = this;
函数中的 this(默认)
在 JavaScript 函数中,函数的拥有者默认绑定 this
因此,在函数中,this
指的是全局对象 [object Window]
。
function myFunction() {
return this;
}
派生类
不像基类的构造函数,派生类的构造函数没有初始的 this 绑定。在构造函数中调用 super() 会生成一个 this 绑定,并相当于执行如下代码,Base为基类:
this = new Base();
注意:在调用 super() 之前引用 this 会抛出错误。
派生类不能在调用 super() 之前返回,除非其构造函数返回的是一个对象,或者根本没有构造函数。
class A {}
class B extends A {}
class C extends A {
constructor() {
return {X: 12};
}
}
class D extends A {
constructor() {}
}
new B();
new C();
new D(); // ReferenceError
bind方法
ECMAScript 5 引入了 Function.prototype.bind()。调用f.bind(someObject)会创建一个与f具有相同函数体和作用域的函数,但是在这个新函数中,this将永久地被绑定到了
bind
的第一个参数,无论这个函数是如何被调用的。
箭头函数
在箭头函数中,this与封闭词法环境的this保持一致。在全局代码中,它将被设置为全局对象
注意:如果将this传递给call、bind、或者apply来调用箭头函数,它将被忽略。不过你仍然可以为调用添加参数,不过第一个参数(thisArg)应该设置为null。