什么是词汇'这个'?

时间:2016-01-09 17:33:48

标签: javascript ecmascript-6

有人可以给我一个关于词汇的简要介绍吗?

  

“箭头函数表达式(也称为胖箭头函数)与函数表达式相比具有更短的语法,并且词汇绑定此值(不绑定它自己的this,arguments,super或new.target)。箭头函数总是匿名的。“

这是否意味着当我使用'胖箭'函数中的'this'引用调用函数成员时,'this'总是指封闭的'this'?

6 个答案:

答案 0 :(得分:23)

您似乎对箭头函数中this的内容有了正确的理解。我会提供一个解释,我认为会增加对话,并希望巩固你的理解。

正如您可能知道的那样,当您定义一个函数并在其中使用一个变量时,它会检查该变量是否已在其范围内定义。如果是的话,它会使用它!如果没有,它将检查该变量定义的封闭范围。它会一直检查封闭范围,直到找到变量或达到全局范围。现在,隐式地为箭头函数的函数定义为您定义this。因此,当您尝试在其范围内使用this时,他们永远不会检查封闭范围(因为他们在自己的范围内找到它!)。箭头函数不定义它们自己的this,因此它们会转到封闭范围并查找它,就像它们尝试在其范围中使用的任何变量一样。

答案 1 :(得分:9)

作为描述箭头函数中this行为的一种方式,术语“词汇this”介于混淆和错误之间。

行为非常简单,箭头函数中的this指的是周围函数中的this - 或者只是说箭头函数可以更简单,更准确不定义(或“绑定”)自己的this

遗憾的是,“词汇this”的术语可能因MDN article on arrow functions中的措词选择不当而延续(直到最近还鼓励人们使用过时的术语“胖箭头功能”) 。这已经被清理干净了。另请注意,规范从不在箭头函数中使用与this相关的术语“词法”。我很想知道是谁想出了这个表达方式。

答案 2 :(得分:7)

假设您有一个点击监听器。在那个监听器中,您正在执行一些AJAX操作,如setTimeout。达到设定的时间后,将执行回调中的代码。在该回调中,您可能已访问this以更改所单击按钮的颜色。但由于AJAX操作,控件将脱离上下文。 ES2015引入了箭头功能来解决这个问题。箭头函数捕获封闭上下文的this值。

示例用例是:

$('.btn').click(function () {
    setTimeout(function () {
        $(this).text('new'); 
        // This will cause an error since function() defines this as the global object.
    } ,100); 
}); 

为了避免这种情况:

$('.btn').click(function () { // <- Enclosing context
    setTimeout( () => {
        $(this).text('new')  } 
        // This works, because this will be set to a value captured from the enclosing context.
      ,100);
});

答案 3 :(得分:3)

wrote an article about this,其要点是:考虑“词汇这个”的含义。 担心箭头功能中“this”的含义。你已经知道了(或者至少,如果你不知道,那就是你自己对某些外部功能范围的混淆,而不是箭头功能的错误)。

多年来,您可能已经习惯于担心当您需要在某些嵌套或更高阶函数中使用它时,“this”最终会有什么意义。但是使用箭头功能,你可以停止担心它。你几乎肯定已经知道你现在所处的环境中“this”指的是什么:但是......在箭头功能中,它没有改变。因此,您可以将箭头函数视为简单的情况,将function(){}视为更复杂的函数。

你是否编写了一些函数并启动了一个if(){}块,并担心“this”可能会在其中发生什么变化?没有?与箭头功能相同。这就是“词汇这个”的含义。这意味着“Hakuna matata。”

答案 4 :(得分:0)

  

这是否意味着当我使用&#39;这个&#39;来调用函数成员时来自“胖箭”的评论&#39;功能&#39;这个&#39;总是指封闭的&#39;这个&#39;?

您的查询的答案是。正如您已经说过,胖箭头函数没有this引用,因此它们使用封闭上下文的引用,这反过来又让我们有机会控制对this的调用的方式在一个胖箭头函数内会响应。

例如:

在使用this的对象内部使用胖箭头函数会查找外部上下文。在这种情况下,上下文为window

var foo = {
  bar: () => this.baz    // 'this' is window      
}

但是,如果您使用公共类字段语法的ES6语法:

class MyClass {
  handleEvent = () => {
    this.letsCode();    // 'this' is instance of MyClass
  }
}

还有许多其他实例(比如使用React的render函数来设置点击侦听器),这些实例超出了使用胖箭头函数和this的问题的范围适当地限制在使用它的环境中,从而为我们提供控制其性质的便利。希望它有所帮助!

答案 5 :(得分:-1)

在es6 fat arrow函数中使用它,使得它具有词法范围,因为在该特定范围内引用的内容被分配给它,这与正常的es5函数声明不同,后者继续检查引用它的内容从最里面的范围到全局范围,直到它找到它。

function foo() {
setTimeout(() => {
    // `this` here is lexically adopted from `foo()`
    console.log( this.a );
},100);
}
var obj = {
  a:2
};
foo.call(obj); //2

与此同时,在es6之前,有一种方法可以在javascript中实现词法作用域,方法是将一个this关键字分配给一个变量,该变量在一定程度上使得本地化为范围

function foo() {
var self = this; // lexical capture of `this`
setTimeout( function(){
    console.log( self.a );
}, 100 );
}
var obj = {
  a: 2;
};
foo.call(obj); //2