美文网首页
箭头函数

箭头函数

作者: 王康_Wang | 来源:发表于2017-02-06 14:33 被阅读0次

    箭头函数就是个简写形式的函数表达式,并且它拥有词法作用域的this值(即不会新产生自己作用域下的this, arguments, supernew.target等对象)。此外,箭头函数总是匿名的。

    箭头函数的引入有两个方面的影响:一是更简短的函数书写,而是对 this 的词法解析。

    更短的函数

    在一些函数式编程模式里,更短的函数书写方式很受欢迎。试比较:

    var a = [
      "Hydrogen",
      "Helium",
      "Lithium",
      "Beryl­lium"
    ];
    
    var a2 = a.map(function(s){ return s.length });
    
    var a3 = a.map( s => s.length );
    
    不绑定 this

    在箭头函数出现之前,每个新定义的函数都有其自己的 this 值(例如,构造函数的 this 指向了一个新的对象;严格模式下的函数的 this 值为 undefined;如果函数是作为对象的方法被调用的,则其 this 指向了那个调用他的对象)。在面向对象风格的办成中,这杯证明是非常恼人的事情。

    function Person() {
      // 构造函数 Person() 定义的 `this` 就是新实例对象自己
      this.age = 0;
      setInterval(function growUp() {
        // 在非严格模式下,growUp() 函数定义了其内部的 `this`
        // 为全局对象, 不同于构造函数Person()的定义的 `this`
        this.age++; 
      }, 1000);
    }
    
    var p = new Person();
    

    在 ECMAScript 3/5 中,这个问题可以通过新增一个变量来指向期望的 this 对象,然后将该变量放到闭包中来解决。

    function Person() {
      var self = this; // 也有人选择使用 `that` 而非 `self`. 
                       // 只要保证一致就好.
      self.age = 0;
    
      setInterval(function growUp() {
        // 回调里面的 `self` 变量就指向了期望的那个对象了
        self.age++;
      }, 1000);
    }
    

    除此之外,还可以使用bind函数,把期望的this值传递给 growUp()函数。
    箭头函数则会捕获其所在上下文的this值,作为自己的this值,因此下面的额代码将如期运行。

    function Person(){
      this.age = 0;
    
      setInterval(() => {
        this.age++; // |this| 正确地指向了 person 对象
      }, 1000);
    }
    
    var p = new Person();
    
    与 strict mode 的关系

    考录到 this 是词法层面上的,严格模式中与 this 相关的规则都将被忽略。

    var f = () => {'use strict'; return this};
    f() === window; // 或全局对象
    
    使用 call 或 apply 调用

    由于 this 已经在此法层面完成了绑定,通过 call() 或 apply() 方法调用一个函数时,只是传入了参数而已,对 this 并没有什么影响:

    var adder = {
      base : 1,
        
      add : function(a) {
        var f = v => v + this.base;
        return f(a);
      },
    
      addThruCall: function(a) {
        var f = v => v + this.base;
        var b = {
          base : 2
        };
                
        return f.call(b, a);
      }
    };
    
    console.log(adder.add(1));         // 输出 2
    console.log(adder.addThruCall(1)); // 仍然输出 2(而不是3 ——译者注)
    
    不绑定 arguments

    将头函数不会在其内部爆出 arguments 对象:arguments.length, arguments[0], arguments[1] 等等,都不会指向箭头函数的 arguments,而是指向了箭头函数所在作用域的一个明为 argument 的值(如果有的活,否则,就是 undefined。)。

    var arguments = 42;
    var arr = () => arguments;
    
    arr(); // 42
    
    function foo() {
      var f = () => arguments[0]; // foo's implicit arguments binding
      return f(2);
    }
    
    foo(1); // 1
    

    降头函数没有自己的 arguments 对象,不过在大多数情形下, rest参数可以给出一个解决方案:

    function foo() { 
      var f = (...args) => args[0]; 
      return f(2); 
    }
    
    foo(1); // 2
    
    像方法一样使用箭头函数

    如上所述,箭头函数表达式对没有方法名的函数时最合适的,让我们试着把他们作为方法时发生了什么。

    'use strict';
    var obj = {
      i: 10,
      b: () => console.log(this.i, this),
      c: function() {
        console.log( this.i, this)
      }
    }
    obj.b(); // prints undefined, Window
    obj.c(); // prints 10, Object {...}
    

    相关文章

      网友评论

          本文标题:箭头函数

          本文链接:https://www.haomeiwen.com/subject/ylgeittx.html