箭头函数

先来看一段代码:

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

 

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

 

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

 

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

 

二、箭头函数的this

 

箭头函数没有它自己的this值,箭头函数内的this值继承自外围作用域。
 
this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为它没有this,所以也就不能用作构造函数。
 

var col = 3
var obj = {
    col: 5,
    show: function ) {
          console.logthis.col)
    }
}
obj.show)    // 5

 
分析:
     调用者是obj,所以this指向obj
 

var col = 3
var obj = {
    col: 5,
    show: ) => console.logthis.col)
}
obj.show)    // 3

 
分析:
     因为是箭头函数,var定义的obj,作用域在全局,所以此时的this指向window
 

let col = 3
let obj = {
    col: 5,
    show: ) => console.logthis.col)
}
obj.show)    // undefined

 
分析:
     因为是let声明,let、const、class命令声明的全局变量是不属于顶层对象的属性的,所以,this就既不指向window,也不指向obj

 

function Person) {
    // 构造函数 Person) 定义的 `this` 就是新实例对象自己
    this.age = 0;
    setIntervalfunction 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;
    setIntervalfunction 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 : functiona) {
    var f = v => v + this.base;
    return fa);
  },

  addThruCall: functiona) {
    var f = v => v + this.base;
    var b = {
      base : 2
    };
           
    return f.callb, a);
  }};

console.logadder.add1));        // 输出 2
console.logadder.addThruCall1)); // 仍然输出 2(而不是3 ——译者注)

 

分析如下:

 

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

 

2、adder.addThruCall1)执行addThruCall,返回f.callb, 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 f2);}

foo1); // 3

 

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

 

function foo) { 
  var f = ...args) => args[0]; 
  return f2); 
}

foo1); 
// 2

 

四、注意事项

 

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

 

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

 

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

 

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

 

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

 

var func = x => x * x;                 
// 简写函数 省略return

var func = x, y) => { return x + y; };
//常规编写 明确的返回值

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注