"this" 在 ES6 中的箭头函数中指的是什么?

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

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

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

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

Arrow functions capture the this value of the enclosing context

function Person(){
  this.age = 0;

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

var p = new Person();

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

希望这个代码展示可以让您更清楚地了解。基本上,箭头函数中的 '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 

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

动态名称绑定

this 指的是调用该方法的对象。这是关于 SO 的定期阅读句子。但它仍然只是一个词组,相当抽象。这句话有对应的码型吗?

是的,有:

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

// the important patterns: applying methods

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

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

还有一个重要的代码模式需要注意:

"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

和之前的模式非常相似,只是少了括号。但后果是相当大的:当你将 m 传递给函数 f 时,你从它的 object/context o 中取出 m。它现在被连根拔起,this 没有任何意义(假定为严格模式)。

词汇(或静态)名称绑定

箭头函数没有自己的 this/super/arguments 绑定。他们从父词法范围继承它们:

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]

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

bazo.bar调用时,箭头函数被o.bar包围(o.bar形成其父词法作用域),可以继承o.barthis 绑定。 o.baro 上被调用,因此它的 this 绑定到 o.

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

// 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]
}

so 'this' in fat arrow function is not bound, means you can't make anything bind to 'this' here, .apply won't, .call won't, .bind won'吨。 'this' 当您在文本编辑器中写下代码文本时,胖箭头函数会被绑定。 'this' in fat arrow function 在这里是字面意思。您在文本编辑器中编写的代码就是您的应用 运行 在 repl 中的内容。 在 fat arror 中绑定的 'this' 永远不会改变,除非您在文本编辑器中更改它。 对不起我的台球英语...

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

这是避免将 var self 分配给 this 的非常有用的方法,它在 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…}

在另一个例子中,如果你点击下面的年龄按钮

<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 error: Uncaught TypeError: Cannot read property 'getFullYear' of undefined on line 18

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

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

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

它将起作用,因为此范围在 person2 中已更改

箭头函数从不与 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'

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

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

With arrow functions there are no binding of this.

In regular functions the this keyword represented the object that called the function, which could be the window, the document, a button or whatever.

With arrow functions the this keyword always represents the object that defined the arrow function.

// 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>

相关问题:

来自 -

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

Does not have its own bindings to this or super, and should not be used as methods.

Arrow functions establish "this" based on the scope the Arrow function is defined within.

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

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

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

你也可以有一个像这样的getter,它没有function关键字,但由于return声明而有点长,也可以访问其他成员函数:

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