在JavaScript中,this是一个特殊的关键字,用于表示函数执行的上下文对象,也就是当前函数被调用时所在的对象。由于JavaScript的函数调用方式多种多样,this的指向也因此而变化。本文将介绍JavaScript中this的指向及绑定规则,包括默认绑定、隐式绑定、new绑定、显式绑定和箭头函数中的this规则。
1. 默认绑定
默认绑定指的是在独立函数调用的情况下,this会指向全局对象(浏览器环境下为window对象,严格模式下为undefined)。例如:
function foo() {
console.log(this);
}
foo(); // 在浏览器环境下输出window对象,在严格模式下输出undefined
无论是多层调用,只要是使用默认调用的方法,this的指向都会是全局对象。
2. 隐式绑定
隐式绑定是指通过某个对象进行调用的情况下,this会指向调用该函数的对象。例如:
function foo() {
console.log(this);
}
var obj = {
name: "sss",
foo: foo
};
obj.foo(); // this指向obj对象
无论多少层调用,只要调用的方法是通过某个对象发起的,this都指向调用该函数的对象。
3. new绑定
在JavaScript中,函数可以当作构造函数使用,使用new关键字调用函数时,会执行以下操作:
- 创建一个全新的对象;
- 这个新对象会被执行prototype连接;
- 这个新对象会绑定到函数调用的this上(this的绑定在这个步骤完成);
- 如果函数没有返回其他对象,表达式会返回这个新对象。
例如:
function Person(name) {
console.log(this);
this.name = name;
}
var p = new Person("aaa");
console.log(p); // p为新创建的Person对象
4. 显式绑定
如果不希望在对象内部包含函数的引用,同时又希望在某个对象上进行强制调用,可以使用call
、apply
、bind
方法。
4.1 apply
方法
apply
方法用于绑定函数的this
对象,将this
绑定到传入的对象上。该方法传入的参数是一个对象和一个参数数组。
function foo(name, age, height) {
console.log(this);
console.log("打印参数:", name, age, height);
}
var obj = {
name: "zzz"
};
foo.apply(obj, ["aaa", 30, 1.98]); // this指向obj对象
4.2 call
方法
call
方法也用于绑定函数的this
对象,但是参数需要逐个传入。
function foo(name, age, height) {
console.log(this);
console.log("打印参数:", name, age, height);
}
var obj = {
name: "zzz"
};
foo.call(obj, "aaa", 30, 1.98); // this指向obj对象
4.3 apply
和call
的第一个参数
apply
和call
的第一个参数是用来绑定this
对象的,可以是任意对象,甚至是window
、Number
、String
对象。
function foo(name, age, height) {
console.log(this);
}
var obj = {
name: "zzz"
};
foo.apply(obj, "aaa", 30, 1.98); // this指向obj对象
foo.call(window); // this指向window对象
foo.call(123); // this指向Number对象
foo.call("string"); // this指向String对象
4.4 bind
方法
bind
方法也用于绑定函数的this
对象,但不会立即执行函数,而是返回一个新的函数。