ES6 中箭头函数中的“this”指的是什么?

What does "this" refer to in arrow functions in ES6?

提问人:temporary_user_name 提问时间:2/7/2015 最后编辑:Nexotemporary_user_name 更新时间:11/29/2022 访问量:22648

问:

我在几个地方读到,关键的区别在于箭头函数的词法绑定。这一切都很好,但我实际上不知道这意味着什么。this

我知道这意味着它在定义函数主体的大括号范围内是唯一的,但我实际上无法告诉您以下代码的输出,因为我不知道指的是什么,除非它指的是胖箭头函数本身......这似乎没有用。this

var testFunction = () => {
  console.log(this)
};
testFunction();

javascript 这个 ecmascript-6 箭头函数

评论

6赞 Barmar 2/7/2015
它只是从包含范围捕获 的值,将其视为任何其他变量。this
1赞 Barmar 2/7/2015
这样你就不必在函数中做这些操作,然后在函数中使用。var self = this;self
5赞 2/7/2015
在您的例子中,没有封闭上下文,或者它是全局上下文或模块上下文,在这种情况下,无论它是什么,很可能是 null 或 window。换句话说,它的值与在函数赋值之前添加 a 的值完全相同。thisthisconsole.log(this)

答:

46赞 Dave 2/7/2015 #1

箭头函数捕获封闭上下文的 this

function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| properly refers to the person object
  }, 1000);
}

var p = new Person();

因此,为了直接回答您的问题,箭头函数内部的值将与分配箭头函数之前的值相同。this

评论

4赞 temporary_user_name 5/19/2017
@torazaburo迟来的回答——答案是,这取决于原始问题中代码片段的放置位置。如果它位于顶层,则如果我们在浏览器中并且处于 Node 环境中,则为对象。关键是,箭头函数对 的值没有影响thiswindowmodule.exportsthis
4赞 Kevin 11/12/2017
@dave的评论,“在你的箭头函数中,它的值将与分配箭头函数之前的值相同”,这是最终让我点击它的原因。this
9赞 Xin 6/23/2016 #2

希望这个代码展示能给你更清晰的想法。基本上,箭头函数中的“this”是“this”的当前上下文版本。查看代码:

// 'this' in normal function & arrow function
var this1 = {
    number: 123,
    logFunction: function () { console.log(this); },
    logArrow: () => console.log(this)
};
this1.logFunction(); // Object { number: 123}
this1.logArrow(); // Window 

评论

3赞 Barleby 3/13/2019
非常简短和很好的例子。使用时,该值是在调用/调用函数时创建的。因此,当您调用它时,您将其作为对象的方法调用并引用 this1 文本对象。另一方面,如果使用箭头函数,则不会根据调用/调用的方式创建值,而是从词法范围继承它,在本例中是对象,其中定义了 this1 obejct。functionthisthis1.logFunction()this1thisthiswindow
24赞 user6445533 9/27/2016 #3

为了提供大局,我将解释动态绑定和词汇绑定。

动态名称绑定

this指调用方法的对象。这是 SO 上经常阅读的句子。但它仍然只是一个短语,相当抽象。这句话有对应的 Code Pattern 吗?

是的,有:

const o = {
  m() { console.log(this) }
}

// the important patterns: applying methods

o.m(); // logs o
o["m"](); // logs o

m是一种方法,因为它依赖于 . 或 means 应用于 。这些模式是我们著名的短语的 Javascript 翻译。thiso.m()o["m"]()mo

您还应该注意另一个重要的 Code Pattern:

"use strict";

const o = {
  m() { console.log(this) }
}

// m is passed to f as a callback
function f(m) { m() }

// another important pattern: passing methods

f(o.m); // logs undefined
f(o["m"]); // logs undefined

它与前面的模式非常相似,只是缺少括号。但后果是相当大的:当你传递给函数时,你会退出它的对象/上下文。它现在被连根拔起,什么也没提及(假设为严格模式)。mfmothis

词法(或静态)名称绑定

箭头函数没有自己的绑定。它们从父词法范围继承它们:thissuperarguments

const toString = Object.prototype.toString;

const o = {
  foo: () => console.log("window", toString.call(this)),
      
  bar() {
    const baz = () => console.log("o", toString.call(this));
    baz();
  }
}

o.foo() // logs window [object Window]
o.bar() // logs o [object Object]

除了全局作用域(在浏览器中)之外,只有函数才能在 Javascript 中形成作用域(以及 ES2015 中的块)。当调用箭头函数时,没有周围的函数可以从中继承其 .因此,它捕获绑定到对象的全局范围的绑定。Window{}o.foobazthisthisWindow

当被调用时,箭头函数被 包围(形成其父词法作用域),并且可以继承 的绑定。 被调用,因此它绑定到 .bazo.baro.baro.baro.barthiso.barothiso

评论

0赞 Reza 2/15/2021
你能帮帮我吗,为什么没有严格模式,它会记录窗口,但使用严格模式,它会记录未定义?严格模式的哪个属性是这样做的?
1赞 Plasmatium 4/12/2017 #4

您可以按照以下方式尝试理解它

// whatever here it is, function or fat arrow or literally object declare
// in short, a pair of curly braces should be appeared here, eg:
function f() {
  // the 'this' here is the 'this' in fat arrow function below, they are
  // bind together right here
  // if 'this' is meaningful here, eg. this === awesomeObject is true
  console.log(this) // [object awesomeObject]
  let a = (...param) => {
    // 'this is meaningful here too.
    console.log(this) // [object awesomeObject]
}

所以胖箭头函数中的“this”是没有绑定的,这意味着你不能在这里让任何东西绑定到“this”,.apply不会,.call不会,.bind不会。当您在文本编辑器中写下代码文本时,FAT 箭头函数中的“this”是绑定的。胖箭头函数中的“this”在这里是字面意思。你的代码在文本编辑器中写的内容就是你的应用在 repl 中运行的内容。 除非您在文本编辑器中更改它,否则 fat arror 中的“this”绑定永远不会改变。 对不起我的游泳池英语...

2赞 Alireza 9/22/2017 #5

箭头函数指向 Es6 中的周围父函数,这意味着它不像 ES5 中的匿名函数那样作用域......this

这是避免将 var self 分配给此的非常有用的方法,这在 ES5 中被广泛使用......

请看下面的例子,在对象中分配一个函数:

var checkThis = {
  normalFunction: function () { console.log(this); },
  arrowFunction: () => console.log(this)
};

checkThis.normalFunction(); //Object {}
checkThis.arrowFunction(); //Window {external: Object, chrome: Object, document: document, tmpDebug: "", j: 0…}
0赞 Hamit YILDIRIM 5/27/2019 #6

在另一个示例中,如果单击下面的年龄按钮

<script>
var person = {
    firstName: 'John',
    surname: 'Jones',
    dob: new Date('1990-01-01'),
    isMarried: false,
    age: function() {
        return new Date().getFullYear() - this.dob.getFullYear();
    }
};

var person2 = {
    firstName: 'John',
    surname: 'Jones',
    dob: new Date('1990-01-01'),
    isMarried: false,
    age: () => {
        return new Date().getFullYear() - this.dob.getFullYear();
    }
};

</script>



<input type=button onClick="alert(person2.age());" value="Age">

它会抛出这样的异常

×JavaScript 错误:未捕获的 TypeError:无法读取属性 第 18 行 undefined 的“getFullYear”

但是如果你改变 person2 的这一行

return new Date().getFullYear() - this.dob.getFullYear(); 

return new Date().getFullYear() - person2.dob.getFullYear();

它会起作用,因为这个范围在 person2 中发生了变化

1赞 TrickOrTreat 7/31/2019 #7

箭头函数从不与关键字绑定this

var env = "globalOutside";
var checkThis = {env: "insideNewObject", arrowFunc: () => {
console.log("environment: ", this.env);
} }

checkThis.arrowFunc()   // expected answer is environment: globalOutside

// Now General function 
var env = "globalOutside";
var checkThis = {env: "insideNewObject", generalFunc: function() {
console.log("environment: ", this.env);
} }
checkThis.generalFunc() // expected answer is enviroment: insideNewObject

// Hence proving that arrow function never binds with 'this'
1赞 LSSJ Λlpha 7/5/2020 #8

箭头函数中使用时,这将始终引用全局对象。使用常规函数声明来引用本地对象。此外,您可以使用对象名称作为上下文(object.method,而不是 this.method),以引用本地对象而不是 global(window)。

0赞 Ben.S 7/5/2021 #9

箭头函数与常规函数的区别:(摘自 w3schools)

使用箭头函数时,没有对此的绑定。

在常规函数中,this 关键字表示调用函数的对象,可以是窗口、文档、按钮或其他任何内容。

对于箭头函数,this 关键字始终表示定义箭头函数的对象。

// Regular Function:
hello = function() {
  document.getElementById("demo").innerHTML += this;
}

// The window object calls the function:
window.addEventListener("load", hello);

// A button object calls the function:
document.getElementById("btn").addEventListener("click", hello);

// -------------------------------------------

// Arrow function
hello2 = () => {
  document.getElementById("demo2").innerHTML += this;
}

// The window object calls the function:
window.addEventListener("load", hello2);

// A button object calls the function:
document.getElementById("btn2").addEventListener("click", hello2);
<p><i>With a regular function this represents the <b>object that calls the function</b>:</i></p>

<button id='btn'>click me regular function</button>

<p id="demo">Regular function: </p>

<hr>

<p><i>With arrow function this represents the <b>owner of the function(=the window object)</b>:</i></p>

<button id='btn2'>click me arrow function</button>

<p id="demo2">Arrow function: </p>

0赞 Manohar Reddy Poreddy 12/14/2021 #10

相关问题:

来自 - 为什么我不能在箭头函数中访问“this”?

我们从这里知道以下内容:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

与 this 或 super 没有自己的绑定,不应用作方法。

箭头函数根据定义箭头函数的范围建立“this”。

使用箭头函数有问题,所以创建了一个类(可以是函数),并在箭头函数中访问类变量,从而使用没有关键字的箭头函数实现了更小的功能:thisfunction

class MyClassOrFunction {
    values = [];
    size = () => this.values.length;
    isEmpty = () => this.size() === 0;
}

let obj = new MyClassOrFunction();
obj.size(); // function call here

你也可以有一个这样的 getter,它没有关键字,但由于语句而稍长一些,也可以访问其他成员函数:functionreturn

class MyClassOrFunction {
    values = [];
    size = () => this.values.length;
    get length() {  return this.size();  }
}
let obj = new MyClassOrFunction();
obj.length; // NOTE: no function call here