JavaScript中this是一个令人困惑但关键的概念,它在不同的绑定下指向不同的对象或值。在本文中,我们将探讨五种绑定规则,并介绍箭头函数是如何在本文this中语境中表现的。
一、为什么用this?
一句话,简化代码的书写。学习 this
是 JavaScript 中至关重要的一部分,因为它影响着代码中函数的行为,尤其是在面向对象和事件处理等方面。
二、this的五种规则
1.默认绑定规则
默认绑定规则非常简单:函数在哪个词法作用域中生效,this就指向哪里。当一个函数独立调用时,this默认指向全局对象,通常是下面window(浏览器环境)。以下是一个例子:
scss
function globalFunction() {
console.log(this); // 在浏览器中输出 window
}
globalFunction();
2. 隐式绑定规则
当一个函数被对象所拥有时,且调用时,函数的this
指向该对象。这就是隐式绑定。考虑以下例子:
javascript
const myObject = {
prop: "I am part of the object",
myMethod: function () {
console.log(this.prop);
}
};
myObject.myMethod(); // 输出 "I am part of the object"
3.隐式丢失
隐式丢失是指当函数被多个对象链式调用时,this
指向引用函数的那个对象。如果函数被提取出来,this
可能会失去原有的绑定。看一个示例:
ini
const obj1 = {
value: 42,
getValue: function () {
return this.value;
}
};
const obj2 = {
value: 17
};
const getValueFromObj2 = obj1.getValue.bind(obj2);
console.log(getValueFromObj2()); // 输出 17
4. new绑定
当使用new
关键字调用函数时,this
会指向新创建的实例对象。这种绑定方式常用于构造函数:
ini
function Animal(name) {
this.name = name;
}
const cat = new Animal("Fluffy");
console.log(cat.name); // 输出 "Fluffy"
5.显示绑定
通过call
、apply
和bind
,我们可以显式地指定函数内部的this
。下面我们将详细解析这三种方法:
1、call
方法:
该call
方法用于调用具有指定this
值和单独提供的参数的函数。这是一个例子:
javascript
function greet(name) {
console.log(`Hello, ${name}! My name is ${this.name}.`);
}
const person = { name: 'John' };
greet.call(person, 'Alice');
// 输出: Hello, Alice! My name is John.
在此示例中,call
用于调用作为值的greet
函数。值后面的附加参数(在本例中)将作为其参数传递给函数。
2、apply
方法:
与 类似call
,该apply
方法用于调用具有指定this
值和参数的数组或类数组对象的函数。这是一个例子:
javascript
function add(a, b) {
console.log(`${this.name} added: ${a + b}`);
}
const calculator = { name: 'CASIO' };
add.apply(calculator, [3, 7]);
// 输出: CASIO added: 10
在此示例中,apply
用于调用作为值的add
函数。第二个参数是一个数组,它作为单独的参数传递给函数。
3、bind
方法:
该bind
方法创建一个具有指定this
值和可选初始参数的新函数。但是,它不会立即调用该函数;相反,它返回一个可以稍后调用的新函数。这是一个例子:
javascript
function displayInfo(age, city) {
console.log(`${this.name} is ${age} years old and lives in ${city}.`);
}
const personInfo = { name: 'Jane' };
const boundFunction = displayInfo.bind(personInfo, 25);
boundFunction('New York');
// Output: Jane is 25 years old and lives in New York.
在此示例中,bind
用于创建一个新函数 ( boundFunction
),并将其personInfo
作为this
值和25
初始参数。当boundFunction
稍后用 调用时'New York'
,它将提供的参数附加到最初绑定的参数。
概括:
call
this
:调用具有指定值和单独参数的函数。apply
this
:使用指定值和参数的数组或类似数组的对象调用函数。bind
:使用指定this
值和可选初始参数创建一个新函数,但不立即调用该函数。
这些方法提供了管理this
函数上下文的灵活性,允许开发人员控制函数在不同对象或上下文中的执行方式。
三、箭头函数的特殊性
在上面的例子中,箭头函数与普通函数在this
上有所不同。箭头函数没有自己的this
,它会捕获其外层的普通函数的this
。考虑下面的例子:
ini
function outerFunction() {
const arrowFunction = () => {
console.log(this);
};
arrowFunction();
}
const obj = { prop: "I am an object" };
outerFunction.call(obj); // 输出 { prop: "I am an object" }
在箭头函数中,this
始终指向outerFunction
被调用时的this
,而不是箭头函数被调用时的this
。这种特性使得箭头函数在某些情况下更容易理解和使用。同时也要注意!箭头函数不能做构造函数!
javascript
var Foo = () => {
}
new Foo();
// 箭头函数不能做构造函数
//输出会报错
总结
理解JavaScript中的this
是成为一个高效开发者的关键。通过默认绑定、隐式绑定、隐式丢失、显示绑定和new
绑定,我们可以更好地掌握函数在不同上下文中的行为。同时,箭头函数的特殊性使得我们能够更方便地处理this
问题,但也需要注意其与普通函数的差异。通过深入研究这些概念,我们能够写出更健壮、可维护的JavaScript代码。