Javascript 是';箭头函数';和';功能';等效/可互换?

Javascript 是';箭头函数';和';功能';等效/可互换?,javascript,ecmascript-6,arrow-functions,Javascript,Ecmascript 6,Arrow Functions,ES2015中的箭头函数提供了更简洁的语法 我现在可以用箭头函数替换所有函数声明/表达式吗 我要注意什么 示例: 构造函数 function User(name) { this.name = name; } // vs const User = name => { this.name = name; }; 原型方法 User.prototype.getName = function() { return this.name; }; // vs User.proto

ES2015中的箭头函数提供了更简洁的语法

  • 我现在可以用箭头函数替换所有函数声明/表达式吗
  • 我要注意什么
示例:

构造函数

function User(name) {
  this.name = name;
}

// vs

const User = name => {
  this.name = name;
};
原型方法

User.prototype.getName = function() {
  return this.name;
};

// vs

User.prototype.getName = () => this.name;
对象(文字)方法

回调

setTimeout(function() {
  // ...
}, 500);

// vs

setTimeout(() => {
  // ...
}, 500);
可变函数

function sum() {
  let args = [].slice.call(arguments);
  // ...
}

// vs
const sum = (...args) => {
  // ...
};

tl;博士:箭头函数和函数声明/表达式不是等价的,不能盲目替换。
如果要替换的函数未使用
this
参数
,并且未使用
new
调用,则选择“是”


通常情况下:视情况而定。箭头函数的行为与函数声明/表达式不同,因此让我们先看看它们的区别:

1。词法
参数

箭头函数没有自己的
参数
绑定。相反,这些标识符像其他变量一样在词法范围内解析。这意味着在箭头函数内部,
this
arguments
指的是箭头函数在环境中定义的
this
arguments
的值(即箭头函数的“外部”):

//使用函数表达式的示例
函数createObject(){
log('createObject`:'内,this.foo);
返回{
傅:42,,
bar:function(){
log('Inside'bar`:',this.foo);
},
};
}
createObject.call({foo:21}).bar();//在createObject中重写`this`
Arrow functions=>迄今为止最好的ES6功能。他们是一个巨大的挑战 ES6的强大补充,我经常使用

等等,您不能在代码中的任何地方都使用箭头函数,它不会在所有情况下都起作用,例如
这个
中箭头函数不可用。毫无疑问,arrow函数是一个很好的补充,它带来了代码的简单性

但是当需要动态上下文时,不能使用arrow函数:定义方法、使用构造函数创建对象、在处理事件时从中获取目标

不应使用箭头函数,因为:
  • 他们没有

    它使用“词法范围”来计算“
    this
    ”的值 应该是。在简单的单词词法范围中,它使用 在函数的主体内部

  • 它们没有
    参数

    箭头函数没有
    参数
    对象。但同样 可以使用rest参数实现功能

    let sum=(…args)=>args.reduce((x,y)=>x+y,0)
    sum(3,3,1)//输出-7
    `

  • 它们不能与新代码一起使用

    箭头函数不能是构造函数,因为它们没有prototype属性

  • 何时使用箭头功能,何时不使用:
  • 不要将函数作为属性添加到对象文字中,因为 无法访问此文件
  • 函数表达式最适合对象方法。箭头函数 最适合于回调或方法,如
    map
    reduce
    forEach
  • 对按名称调用的函数使用函数声明(因为 它们被吊起来了)
  • 对回调使用箭头函数(因为它们往往更简洁)

  • 为了将箭头函数与
    function.prototype.call一起使用,我在对象原型上创建了一个helper函数:

      // Using
      // @func = function() {use this here} or This => {use This here}
      using(func) {
        return func.call(this, this);
      }
    
    用法

      var obj = {f:3, a:2}
      .using(This => This.f + This.a) // 5
    
    编辑

    你不需要助手。你可以做:

    var obj = {f:3, a:2}
    (This => This.f + This.a).call(undefined, obj); // 5
    

    随着ES2015变得越来越流行,关于箭头功能的类似问题也越来越多。我觉得这个问题没有一个好的标准问题/答案,所以我创建了这个。如果你认为已经有一个好的,请让我知道,我会关闭这个重复或删除它。请随意改进示例或添加新的示例。如何?当然,一个普通的问题永远不会像一个被专门写成规范的问题那样好和一般。变量
    this
    非常不同
    timesCalled
    每次调用按钮时仅增加1。这回答了我的个人问题:
    。单击(()=>{})
    。单击(函数(){})
    当在循环中使用时,这两个函数都创建了相同数量的函数,从Plnkr.Related post-Related中的Guid计数中可以看出:。可能值得一提的是,词法
    这个
    也会影响
    超级
    ,并且它们没有
    。prototype
    。还可以指出它们在语法上是不正确的可互换性——箭头函数(
    AssignmentExpression
    )不能放在任何地方,函数表达式(
    PrimaryExpression
    )可以放在任何地方,而且它会经常让人绊倒(特别是因为在主要的JS实现中存在解析错误)。@JMM:“它会让人绊倒很频繁”你能提供一个具体的例子吗?浏览一下规范,似乎可以放置FE但不能放置AF的地方无论如何都会导致运行时错误……当然,我指的是像函数表达式(
    ()=>{}()
    )这样的尝试立即调用箭头函数,或者做类似于
    x |()=>{}
    。这就是我的意思:运行时(解析)错误。(即使是这样,人们也经常认为错误是错误的。)您是否只是试图覆盖那些不会被注意到的逻辑错误,因为它们在解析或执行时不一定会出错
    new
    'ing one是一个运行时错误,对吗?下面是一些在野外出现的链接:,(这是一个异步箭头,但我认为是sa
    var obj = {f:3, a:2}
    (This => This.f + This.a).call(undefined, obj); // 5