什么"这"参考ES6中的箭头功能?

时间:2015-02-06 18:03:46

标签: javascript this ecmascript-6 arrow-functions

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

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

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

9 个答案:

答案 0 :(得分:33)

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将具有与分配箭头函数之前相同的值。

答案 1 :(得分:15)

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

动态名称绑定

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时,您会拉出其对象/上下文m的{​​{1}}。它现在被连根拔起,o没有任何意义(假设严格模式)。

词法(或静态)名称绑定

箭头功能没有自己的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]),只有函数能够在Javascript(和ES2015中的Window块)中形成范围。当调用{}箭头函数时,没有o.foo可以继承其baz的周围函数。因此,它捕获绑定到this对象的全局范围的this绑定。

Window调用baz时,箭头函数被o.bar包围(o.bar形成其父词法范围)并且可以继承o.bar' s o.bar绑定。在this上调用了o.bar,因此其o绑定了this

答案 2 :(得分:3)

希望这段代码能给你更清晰的想法。基本上,箭头函数中的'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 :(得分:2)

箭头函数this指向Es6中的周围父级,意味着它的范围不像ES5中的匿名函数...

避免将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…}

答案 4 :(得分:1)

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

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

所以'这个'在胖箭头功能没有约束,意味着你不能做任何事情绑定到这个'在这里,。应用赢了,.call赢了,.bind赢了。的'这'当你在文本编辑器中记下代码文本时,胖箭头函数被绑定。 '这'在胖箭头功能在这里是有意义的。您的代码在文本编辑器中编写的内容是您的应用程序在repl中运行的内容。 这是什么'除非您在文本编辑器中更改它,否则将永远不会更改胖版本中的绑定。 对不起,我的泳池英语......

答案 5 :(得分: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错误:未被捕获的TypeError:无法读取属性   第18行未定义的'getFullYear'

但是如果您更改person2的这一行

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

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

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

答案 6 :(得分:0)

箭头功能永远不会与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'

答案 7 :(得分:0)

在箭头函数中使用

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

答案 8 :(得分:0)

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

<块引用>

箭头函数没有绑定 this。

<块引用>

在常规函数中,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>