让我向你解释一下什么是“this”。(JavaScript)

2025-06-10

让我向你解释一下什么是“this”。(JavaScript)

原文:https://www.ycmjason.com/blog/2018/06/15.html

  • 本文假设在所有情况下都使用“use strict”
  • 本文也假设你对函数有一些了解,但仍然有点困惑

this在 Javascript 中,这可能是编程世界中最神奇的关键字。它的不可预测性已经达到了前所未有的程度。

超过 9000 了!!!

然而,如果你想成为 JavaScript 大师,完全理解它至关重要。所以,让我试着解释一下什么是this. (如果你不明白,好吧,至少我试过了。)

功能

从函数开始。在本文中,我想将函数分为 3 个不同的类别。

  1. 正常功能
  2. 箭头函数
  3. 绑定函数

正常功能

我将普通函数定义为使用以下方式创建的任何函数...

// function declaration
function magic() {
    ...
}

// function expression
const magic = function() {
    ...
};

// (or if you hate your life)
// function constructor
const magic = new Function('...');
Enter fullscreen mode Exit fullscreen mode

箭头函数

箭头函数基本上是 ES6 箭头函数:

const magic = () => {
    ...
};
Enter fullscreen mode Exit fullscreen mode

绑定函数

可以通过调用Function.prototype.bind普通函数来创建绑定函数。

// magic is created with function declaration/expression/constructor
const bound = magic.bind(...);
Enter fullscreen mode Exit fullscreen mode

调用函数的方法

假设我们有一个函数f(任意类别)。有两种方法可以调用它。

  1. 隐式(直接)调用
  2. 显式调用

隐式(直接)调用

隐式(直接)调用很无聊:

/* f is defined */

// direct call
f();

// or attach it to an object and call it
const obj = {};
obj.fn = f;
obj.fn();
Enter fullscreen mode Exit fullscreen mode

显式调用

显式调用更有趣。你可以使用Function.prototype.call或来调用你的函数Function.prototype.apply

/* f is defined */

// Function.prototype.call
f.call(...);

// Function.prototype.apply
f.apply(...);
Enter fullscreen mode Exit fullscreen mode

快速回顾

让我们快速回顾一下,我们有 3 类功能:

  1. 普通函数 - 使用函数声明/表达式/构造函数创建
  2. 箭头函数 -() => {...}
  3. 绑定函数 - 使用f.bind(...)

调用函数有两种方式:

  1. 隐式(直接)调用 -f()obj.f()
  2. 显式调用 -f.call(...)f.apply(...)

这意味着我们有 6 种不同的场景。

  1. 普通函数+隐式(直接)调用
  2. 普通函数+显式调用
  3. 箭头函数+隐式(直接)调用
  4. 箭头函数 + 显式调用
  5. 绑定函数 + 隐式(直接)调用
  6. 绑定函数 + 显式调用

别慌,没那么可怕。

实际上,箭头函数和绑定函数并不关心隐式/显式调用。因此,这简化为以下四种情况:

  1. 普通函数+隐式(直接)调用
  2. 普通函数+显式调用
  3. 箭头函数
  4. 绑定函数

查找程序this


this下面是在函数中 查找绑定的过程f

练习!

给出magic定义如下:

'use strict';

const magic = function() {
    // a. what is `this`?
    console.log(this);

    const cool = () => {
        // b. what is `this`?
        console.log(this);
    };
    cool();
};

// QUESTION 1
magic();


// QUESTION 2
const apple = { name: 'apple' };
apple.magic = magic;
apple.magic();

// QUESTION 3
const orange = { name: 'orange' };
magic.call(orange);
Enter fullscreen mode Exit fullscreen mode

问题 1.a

按照流程图,我们想要this在中找到magic

  1. 类别magic为正常功能
  2. magic被隐式(直接)调用
  3. magic被称为magic()
  4. 所以this= undefined!!!

问题 1.b

按照流程图,我们想要this在中找到cool

  1. cool是箭头函数的类别
  2. 从问题 1.b中,我们magic知道thisundefined
  3. cool的定义是magic
  4. 所以this=magicthis= undefined

懒惰的讲师

剩下的问题,问题 2.a、2.b、3.a 和 3.b,对于我的流程图来说,都不是太难。所以我就把它们留给大家作为练习吧。

答案

https://repl.it/@ycmjason/What-is-this

单击运行,您将按顺序看到答案(1.a,1.b,2.a,2.b,3.a,3.b)。

笔记

  • 没有“绑定箭头函数”。(() => {...}).bind(...)仍然是原始的箭头函数。
  • 对于隐式调用,只有形状(f()obj.f())重要。其来源并不重要f。考虑以下代码:
const f = obj.f; // obj.f is a normal function
f(); // `this` in the body of `f` is `undefined`!!! not `obj`!!!
Enter fullscreen mode Exit fullscreen mode

更新:

  • 2018 年 7 月 16 日:感谢@joshcheek提醒我this箭头函数的正确绑定!
  • 2018 年 6 月 18 日:感谢 Yong 指出错别字!
鏂囩珷鏉ユ簮锛�https://dev.to/ycmjason/let-me-explain-to-you-what-is-this-javascript-44ja
PREV
我对 React 与 Vue 中“vue”的看法
NEXT
JavaScript 范围 如何在 JavaScript 中创建范围