箭头函数和this

箭头函数

var f = v => v;
//等同于
var f = function () {
	return v
}
  1. 多个参数或不需要参数

    var f = () => 5;
    //等同于
    var f = function () { return 5 }

    var sum = (num1, num2) => num1 + num2;
    //等同于
    var f = function (num1, num2) {
    return num1 + num2
    }

  2. 如果箭头函数的代码块部分多于一条语句,就要使用大括号将他们括起来,并且使用return语句返回。由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。

    //报错
    let getItem = id => {id: id, name: ‘temp’};

    //不报错
    let getItem = id => ({id: id, name: ‘temp’});

下面是一种特殊情况,虽然可以运行,但会得到错误的结果。

let foo = () => { a: 1 };
foo() // undefined

上面代码中,原始意图是返回一个对象{ a: 1 },但是由于引擎认为大括号是代码块,所以执行了一行语句a: 1。这时,a可以被解释为语句的标签,因此实际执行的语句是1;,然后函数就结束了,没有返回值。

如果箭头函数只有一行语句,且不需要返回值,可以采用下面的写法,就不用写大括号了。

let fn = () => void doesNotReturn();
注意
  1. 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

    this对象的指向是可变的,但是在箭头函数中,它是固定的

     function foo () {
     	setTimeout(()=>{
     		console.log('id:', this.id);
     	}, 100);
     }
     
     var id = 21;
     foo.call({id: 42});
     // id:42
    

    箭头函数可以让setTimeout里面的this,绑定定义时所在的作用域,而不是指向运行时所在的作用域。

     function Timer () {
     	this.s1 = 0;
     	this.s2 = 0;
     	// 箭头函数
     	setInterval(() => this.s1++, 1000);
     	//普通函数
     	setInterval(function () {
     		this.s2++;
     	}, 1000);
     }
     var timer = new Timer();
     
     setTimeout(() => console.log('s1: ', timer.s1), 3100);
     setTimeout(() => console.log('s2: ', timer.s2), 3100);
     // s1: 3
     // s2: 0
    

    Timer函数内部设置了两个定时器,分别使用了箭头函数和普通函数。前者的this绑定定义时所在的作用域(即Timer函数),后者的this只想运行时所在的作用域(即全局对象)。所以,3100毫秒之后,timer.s1被更新了3次,而timer.s2一次都没更新。

    箭头函数可以让this指向固定化,这种特性很有利于封装回调函数。

     var handle = {
     	id: '123456',
     	init: function () {
     		document.addEventListener('click', event => this.doSomething(event.type), false);
     	},
     	doSomething: function (type) {
     		console.log('Handling ' + type + ' for ' + this.id)
     	}
     }
    

    上面代码的init方法中,使用了箭头函数,这导致这个箭头函数里面的this,总是指向handle对象。否则,回调函数运行时,this.doSomething这一行会报错,因为此时this指向document对象。

    this指向的固定化(箭头函数使得this从“动态”变成“静态”),并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为它没有this指向,所以也就不能用作构造函数。

    除了this,以下三个变量在箭头函数之中也是不存在的,指向外层函数的对应变量:arguments、super、new.target

    另外,由于箭头函数没有自己的this,所以当然也就不能用call()、apply()、bind()这些方法去改变this的指向。

  2. 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。

  3. 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用rest参数代替。

  4. 不可以使用yield命令,因此箭头函数不能用作Generator函数。

什么是this

函数实际上是对象。每个函数都是Function类型的实例,而且都有与其他引用类型一样具有属性和方法。由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定(函数是对象,函数名是指针)。

函数声明会在解析过程中得到提升,函数表达式则不会。

每个函数在被调用时都会自动取得两个特殊变量:this和arguments。

arguments.callee

this引用的是函数据以执行的环境对象——或者也可以说是this值。在调用函数之前,this的值并不确定,因此this可能会在代码执行过程中引用不同的对象。

call() apply()能够扩充函数赖以运行的作用域。(P117)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值