zoukankan      html  css  js  c++  java
  • [ES6深度解析]6:箭头函数

    前世今生

    <!-- 单行注释

    箭头从一开始就是JavaScript的一部分。第一个JavaScript教程建议用HTML注释包装内联脚本。这将防止不支持JS的浏览器将JS代码错误地显示为文本。你可以这样写:

    <script language="javascript">
    <!--
      document.bgColor = "brown";  // red
    // -->
    </script>
    

    旧的浏览器会看到两个不支持的标签和一个评论;只有新的浏览器才会看到JS代码。为了支持这种奇怪的破解方法,浏览器中的JavaScript引擎将字符<!作为一行注释的开头。没有玩笑。这实际上一直是语言的一部分,直到今天它还在工作,不仅在内联<script>的顶部,而且在JS代码的所有地方。它甚至可以在Node中工作。

    在ES6中,这种注释风格第一次被标准化了。

    --> goes to 操作符

    箭头序列-->也表示一行注释。奇怪的是,在HTML中-->之前的字符是注释的一部分,而在JS中-->之后的行其余部分是注释。这个箭头只在注释出现在一行的开头时表示注释。这是因为在其他上下文中,-->是JS中的一个操作符,“goes to”操作符!

    function countdown(n) {
      while (n --> 0)  // "n goes to zero"
        alert(n);
      blastoff();
    }
    

    <= 小于等于符号

    用来判断是否小于等于某数值

    函数表达式无处不在

    JavaScript的一个有趣特性是,当需要一个函数时,你可以在运行代码的过程中输入该函数。例如,假设试图告诉浏览器当用户单击某个按钮时该做什么。开始键入:

    $("#confetti-btn").click(
    

    jQuery的.click()方法有一个参数:一个函数。没有问题。你可以在这里输入一个函数:

    $("#confetti-btn").click(function (event) {
      playTrumpet();
      fireConfettiCannon();
    });
    

    现在,编写这样的代码对我们来说很自然。所以回想起来很奇怪,在JavaScript普及这种编程之前,许多语言都没有这个特性。当然,Lisp在1958年有函数表达式,也称为lambda函数。但是c++、Python、c#和Java都在没有它们的情况下存在了很多年。目前较新的语言都内置了lambda。我们要感谢JavaScript——以及早期JavaScript程序员无畏地构建了大量依赖lambda的库,从而导致了该特性的广泛采用。

    然而,在我提到的所有语言中,JavaScript的lambda语法是最冗长的。

    // A very simple function in six languages.
    function (a) { return a > 0; } // JS
    [](int a) { return a > 0; }  // C++
    (lambda (a) (> a 0))  ;; Lisp
    lambda a: a > 0  # Python
    a => a > 0  // C#
    a -> a > 0  // Java
    

    现在可以来看看ES6新特性,箭头函数。

    => 箭头函数

    ES6为编写函数引入了一种新的语法:

    // ES5
    var selected = allJobs.filter(function (job) {
      return job.isSelected();
    });
    
    // ES6
    var selected = allJobs.filter(job => job.isSelected());
    

    当您只需要一个带参数的简单函数时,新的箭头函数语法就是Identifier => Expression。可以跳过键入functionreturn,以及一些括号、大括号和分号。

    要编写一个有多个参数(或没有参数,或rest参数或默认参数,或解构参数)的函数,您需要在参数列表周围添加圆括号:

    // ES5
    var total = values.reduce(function (a, b) {
      return a + b;
    }, 0);
    
    // ES6
    var total = values.reduce((a, b) => a + b, 0);
    

    箭头函数可以包含一个语句块而不仅仅是一个表达式。回想一下我们之前的例子:

    // ES5
    $("#confetti-btn").click(function (event) {
      playTrumpet();
      fireConfettiCannon();
    

    改为ES6箭头函数的形式:

    // ES6
    $("#confetti-btn").click(event => {
      playTrumpet();
      fireConfettiCannon();
    });
    

    注意,带有块体{}的箭头函数不会自动返回值。此时要使用return语句,显式返回。

    使用箭头函数返回创建的普通对象时需要注意一点。总是用括号括住对象:

    var chewToys = puppies.map(puppy => {});   // BUG!
    var chewToys = puppies.map(puppy => ({})); // ok
    

    不幸的是,空对象{}空块{}看起来完全一样。ES6中的规则是,紧跟着箭头的{总是被视为块的开始,而不是对象的开始。代码puppy =>{}因此被静默地解释为一个不做任何事情并返回undefined的箭头函数。

    更令人困惑的是,像{key: value}这样的对象字面量看起来就像一个包含标签语句的块--至少在JavaScript引擎看来是这样的。幸运的是{是唯一的二义字符,所以用括号包装对象字面量是你需要记住的唯一技巧。

    this 是什么?

    普通函数函数和箭头函数在行为上有一个细微的区别。箭头函数没有自己的this值。在箭头函数中this的值总是继承自外围作用域。

    this在JavaScript中是如何工作的?其值从何而来?没有简单的答案。如果这在你的脑海中看起来很简单,那是因为你已经处理它很长时间了!

    这个问题经常出现的一个原因是function函数会自动接收this值,不管它们是否需要。你写过这种hack吗?

    {
      ...
      addAll: function addAll(pieces) {
        var self = this;
        _.each(pieces, function (piece) {
          self.add(piece);
        });
      },
      ...
    }
    

    这里,你想在内部函数中写的就是this.add(piece)。不幸的是,内部函数没有继承外部函数的this值。在内部函数中,this将是windowundefined。临时变量self的作用是将外部this值带入内部函数。(另一种方法是在内部函数上使用.bind(this)。两种方式都不是特别漂亮。)

    在ES6中,如果你遵循以下规则,这些Hack代码就会消失:

    // ES6
    {
      ...
      addAll: function addAll(pieces) {
        _.each(pieces, piece => this.add(piece));
      },
      ...
    }
    

    在ES6版本中,注意addAll方法从它的调用者那里接收this。内部函数是一个箭头函数,因此它从外围作用域继承了this。作为奖励,ES6还提供了一种更短的方法来编写对象字面量中的方法!所以上面的代码可以进一步简化:

    // ES6 with method syntax
    {
      ...
      addAll(pieces) {
        _.each(pieces, piece => this.add(piece));
      },
      ...
    }
    

    在旧function箭头函数之间,我可能再也不会键入functoin了。

    箭头函数和非箭头函数之间还有一个细微的区别:箭头函数也没有自己的参数对象arguments。当然,在ES6中,您可能更愿意使用rest参数或默认值。

    本文来自博客园,作者:Max力出奇迹,转载请注明原文链接:https://www.cnblogs.com/welody/p/15176702.html

    如果觉得文章不错,欢迎点击推荐

  • 相关阅读:
    RMAN01009: syntax error: found "dot" 解决方法
    Oracle 11g 新特性 DB_ULTRA_SAFE 参数 说明
    Oracle 11g 新特性 Result Cache(结果高速缓存)说明
    Oracle 11g 新特性 DB_ULTRA_SAFE 参数 说明
    /dev/sdxx is apparently in use by the system; will not make a filesystem here! 解决方法
    CSDN博客之星 投票说明
    Oracle 11g 新特性 – ACFS 说明
    Oracle 与 iptables 和 SELinux 禁用关系 说明
    Vbox 安装 windows Server 2008 R2 报错 Info: An unexpected error has occurred 解决方法
    Oracle 11g 新特性 SecureFiles 说明
  • 原文地址:https://www.cnblogs.com/welody/p/15176702.html
Copyright © 2011-2022 走看看