zoukankan      html  css  js  c++  java
  • 箭头函数

    先来看一段代码:

    var func = new function() { 
          this.a = "func"; 
        } 
     
        // var func2 = function(x) { 
        //     var a = "func2"; 
        //     alert(this.a);     // func           
        //     alert(x);          // func2
        // }
     
        // 箭头函数this指向对象本身
        let func2 = x => {
          let a = 'func2';
          alert(this.a)   // undefined
          alert(x)        // func2
        }
     
        // call改变this指向,将func2的this指向func
        func2.call(func, "func2");

     

    一、什么是箭头函数,为什么使用箭头函数?

     

    箭头函数就是函数的一种简写形式,使用括号包裹参数,跟随一个=>,紧接着是函数体。

     

    ES6中,箭头函数的引入有两个方面的作用:一是更简短的函数书写,二是对this的词法解析。

     

    二、箭头函数的this

     

    箭头函数没有它自己的this值,箭头函数内的this值继承自外围作用域。
     
    this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为它没有this,所以也就不能用作构造函数。
     
    var col = 3
    var obj = {
        col: 5,
        show: function () {
              console.log(this.col)
        }
    }
    obj.show()    // 5
     
    分析:
         调用者是obj,所以this指向obj
     
    var col = 3
    var obj = {
        col: 5,
        show: () => console.log(this.col)
    }
    obj.show()    // 3
     
    分析:
         因为是箭头函数,var定义的obj,作用域在全局,所以此时的this指向window
     
    let col = 3
    let obj = {
        col: 5,
        show: () => console.log(this.col)
    }
    obj.show()    // undefined
     
    分析:
         因为是let声明,let、const、class命令声明的全局变量是不属于顶层对象的属性的,所以,this就既不指向window,也不指向obj

     

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

     

    上面定时器的this并不是指向构造函数的this,这并不是我们想要的。所以想要定时器里面的this指向构造函数,我们可以通过把this的值赋值给变量,然后将该变量放到闭包中来解决。

     

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

     

    我们还可以使用bind函数,把期望的this值传递给growUp函数。当然,我们可以使用箭头函数轻松实现,箭头函数会捕获他所在的上下文的this值,作为自己的this值。

     

    function Person() { 
        this.age = 0; 
        setInterval(() => {
            // 回调里面的 `this` 变量就指向了期望的那个对象了
            this.age++;
        }, 3000);}
    
    var p = new Person();

     

    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 ——译者注)

     

    分析如下:

     

    1、adder.add(1)执行add函数,add返回f(a)也就是f(1)的调用,执行f()函数,f是箭头函数写法,this.base中的this指向对象本身,所以输出2

     

    2、adder.addThruCall(1)执行addThruCall,返回f.call(b, a),call本质是将f的this指向b,所以此时的this.base理应是2,但是因为是箭头函数的写法,this已经在词法层面完成了绑定,通过call或者apply方法调用的时候,只是出入了参数,并没有改变this的指向,所以此时的值还是2.

     

    三、arguments

    箭头函数不会在其内部暴露出参数,也就是说没有自己的arguments:

     

    var arguments = 42;var arr = () => arguments;
    
    arr(); // 42
    
    function foo() {
      var f = (i) => arguments[0]+i; 
      // foo函数的间接参数绑定
      return f(2);}
    
    foo(1); // 3

     

    不过在大多数情形下,rest参数可以给出一个解决方案:

     

    function foo() { 
      var f = (...args) => args[0]; 
      return f(2); 
    }
    
    foo(1); 
    // 2

     

    四、注意事项

     

    1、箭头函数不能用作构造器,和new一起用就会报错

     

    var Foo = () => {};
    var foo = new Foo();
    // TypeError: Foo is not a constructor

     

    2、箭头函数没有原型属性

     

    var Foo = () => {};
    console.log(Foo.prototype);
    // undefined

     

    3、箭头函数既支持简写也支持常规编写

     

    var func = x => x * x;                 
    // 简写函数 省略return
    
    var func = (x, y) => { return x + y; };
    //常规编写 明确的返回值
  • 相关阅读:
    js 获取asp.net TextBox值
    项目笔记一
    如何取GridView中隐藏列的值
    使用bablepolyfill
    border: 0.5px
    选择查询固定位置的数据
    SQL用户数据库权限设置
    Java.1 HelloWorld的分析
    Java.2 面向对象
    【drupal实践】windows下drupal7.22develop版本安装
  • 原文地址:https://www.cnblogs.com/sup9278/p/7448461.html
Copyright © 2011-2022 走看看