JavaScript 开发人员应该理解的 this

简介: 初次接触 this 是在 c# 中,再后来的 JavaScript ,两者在 this 处理上非常相似。但是 JavaScript 是一种基于原型的编程语言,没有类的概念。意味着 this 将指向调用函数的对象,通常称为上下文。当然 this 不止于此,在函数内部的引用可以绑定到不同的对象,这得取决于函数是从哪里被调用。this 问题和变量函数提升是前端面试常见的问题,关于变量提升可以参阅《加深Javascript变量函数声明提升理解》

初次接触 this 是在 c# 中,再后来的 JavaScript ,两者在 this 处理上非常相似。但是 JavaScript 是一种基于原型的编程语言,没有类的概念。意味着 this 将指向调用函数的对象,通常称为上下文。当然 this 不止于此,在函数内部的引用可以绑定到不同的对象,这得取决于函数是从哪里被调用。this 问题和变量函数提升是前端面试常见的问题,关于变量提升可以参阅《加深Javascript变量函数声明提升理解

绑定

在 JavaScript 中,词法环境(Lexical Environments)是一种规范类型,用于根据ECMAScript代码的词法嵌套结构定义标识符与特定变量和函数的关联。一个词法环境由一个环境记录(Environment Record)和一个可能为空的外部词法环境的引用组成。通常,词法环境与ECMAScript代码的特定句法结构有关。例如函数申明、块语句、try语句中的catch等代码每次运算后会产生新的词法环境。

执行上下文(Execution Contexts)是一种规范设备,通过ECMAScript编译器来跟踪代码的运行时评估。在任何时候,每个代理(agent)最多只有一个正在执行代码的执行上下文。

每个执行上下文包含一个环境记录(Environment Record),当 JavaScript 引擎执行代码时,变量和函数名会被添加到环境记录(Environment Record)中,这就是绑定的基本概念,有助于将标识符(变量、函数名)与执行上下文的 this 关键字关联起来。

函数调用

这个很简单,this 是指调用的来源,在函数中的 this 指的是全局对象。

function callAuthor() {
    console.log(this.author);
}
callAuthor(); // undefined
var author = "DevPoint";
callAuthor(); // DevPoint

在严格模式下,this.author 的值为 undefined

let & const

如果在全局级使用 letconst 声明变量,则它们不会存储在全局对象中。相反,在不可访问的声明性环境记录中,因此前面的示例在使用 const 时输出不一样的结果。

function callAuthor() {
    console.log(this.author);
}
const author = "DevPoint";
callAuthor(); // undefined
window.author = "DevPoint";
callAuthor(); // DevPoint

隐式绑定

当函数引用有上下文对象时,隐式绑定规则会把函数中的this绑定到这个上下文对象。对象属性引用链中只有上一层或者说最后一层在调用中起作用。

const thisArticle = {
    title: "JavaScript",
    printTitle: function () {
        console.log(this.title);
    },
};
thisArticle.printTitle(); // JavaScript

如果对象只包含对 printTitle 调用函数的引用,可以获得相同的结果:

function printTitle() {
    console.log(this.title);
}
const thisArticle = {
    title: "JavaScript",
    printTitle: printTitle,
};
thisArticle.printTitle(); // JavaScript

显式绑定

通过callapplybind 方法把对象绑定到this上,叫做显式绑定。

function article() {
    console.log(this.title);
}
const thisArticle = {
    title: "JavaScript",
};
article.call(thisArticle); // JavaScript

callapply 都执行相同的操作,两者的第一个论点应该是这指向什么。如果需要将额外的参数传递给被调用的函数,则会出现差异。

  • 使用 call 时参数作以普通逗号分隔的参数列表传递
  • 使用 apply 时参数以数组方式传递
  • 使用 bind 将创建一个新函数并将其永久绑定到 this

下面创建一个将 this 永久绑定到 thisArticle 的新函数,并将 article 重新分配给该新的永久绑定函数:

function article() {
    console.log(this.title);
}
const thisArticle = {
    title: "JavaScript",
};
const newArticle = article.bind(thisArticle);
newArticle(); // JavaScript

new绑定

new 关键字构造一个新对象, this 指向它。当使用 new 关键字将函数作为构造函数调用时, this 指向创建的新对象。

function Article(title) {
    this.title = title;
}
const thisArticle = new Article("JavaScript");
console.log(thisArticle.title); // JavaScript

箭头函数

使用箭头函数,this 保持与其父作用域相同的值。例如,箭头函数中的 this 值与外面 Article 函数中的 this 值保持一致:

function Article(title) {
    this.title = title;
    this.toUpper = () => {
        return this.title.toUpperCase();
    };
}
const thisArticle = new Article("JavaScript");
console.log(thisArticle.title); // JavaScript
console.log(thisArticle.toUpper()); // JAVASCRIPT

结论

JavaScript 中的 this 是一个容器带来 Bug 的关键字,为了减少类似问题就需要加深对其 this 的理解。从上面的介绍来看,最佳的实践是尽量使用箭头函数。


相关文章
|
14天前
|
JavaScript 前端开发
javascript中的this
javascript中的this
|
14天前
|
JavaScript 前端开发
错综复杂的this:理清你的JavaScript代码中的指向问题
错综复杂的this:理清你的JavaScript代码中的指向问题
|
14天前
|
JavaScript
JS中改变this指向的六种方法
JS中改变this指向的六种方法
|
12天前
|
前端开发 JavaScript
JavaScript:this-关键字,2024中级前端开发面试解答
JavaScript:this-关键字,2024中级前端开发面试解答
|
14天前
|
自然语言处理 JavaScript 前端开发
在JavaScript中,this关键字的行为可能会因函数的调用方式而异
【5月更文挑战第9天】JavaScript中的`this`关键字行为取决于函数调用方式。在非严格模式下,直接调用函数时`this`指全局对象,严格模式下为`undefined`。作为对象方法调用时,`this`指向该对象。用`new`调用构造函数时,`this`指向新实例。通过`call`、`apply`、`bind`可手动设置`this`值。在回调和事件处理中,`this`可能不直观,箭头函数和绑定方法可帮助管理`this`的行为。
17 1
|
14天前
|
JavaScript 前端开发
深入探索JavaScript:如何改变this的指向
深入探索JavaScript:如何改变this的指向
10 2
|
14天前
|
JavaScript 前端开发
【专栏】`Function.prototype.apply` 在JavaScript中用于动态设定函数上下文(`this`)和参数列表
【4月更文挑战第29天】`Function.prototype.apply` 在JavaScript中用于动态设定函数上下文(`this`)和参数列表。它接受两个参数:上下文对象和参数数组。理解`apply`有助于深入JS运行机制。文章分三部分探讨其原理:基本概念和用法、工作原理详解、实际应用与注意事项。在应用中要注意性能、参数类型和兼容性问题。`apply`可用于动态改变上下文、传递参数数组,甚至模拟其他语言的调用方式。通过深入理解`apply`,能提升代码质量和效率。
|
14天前
|
JavaScript 前端开发 数据安全/隐私保护
|
14天前
|
自然语言处理 JavaScript 前端开发
js_关键字this指向哪里?
js_关键字this指向哪里?
8 0
|
14天前
|
JavaScript 前端开发
js开发:请解释this关键字在JavaScript中的用法。
【4月更文挑战第23天】JavaScript的this关键字根据执行环境指向不同对象:全局中指向全局对象(如window),普通函数中默认指向全局对象,作为方法调用时指向调用对象;构造函数中指向新实例,箭头函数继承所在上下文的this。可通过call、apply、bind方法显式改变this指向。
10 1