深入理解JavaScript中的this与箭头函数

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.显示绑定

通过callapplybind,我们可以显式地指定函数内部的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代码。

相关推荐
liang_jy3 小时前
Android UID
android·面试
C雨后彩虹3 小时前
任务总执行时长
java·数据结构·算法·华为·面试
小鸡吃米…4 小时前
Python编程语言面试问题二
开发语言·python·面试
踢球的打工仔4 小时前
jquery的基本使用(3)
前端·javascript·jquery
徐同保4 小时前
js 点击按钮 把文本转成文件并下载下来
开发语言·javascript·ecmascript
LYFlied5 小时前
【每日算法】LeetCode 84. 柱状图中最大的矩形
前端·算法·leetcode·面试·职场和发展
bug总结5 小时前
前端开发中为什么要使用 URL().origin 提取接口根地址
开发语言·前端·javascript·vue.js·html
zwjapple5 小时前
全栈开发面试高频算法题
算法·面试·职场和发展
程序员爱钓鱼5 小时前
Node.js 编程实战:数据库连接池与性能优化
javascript·后端·node.js