ES6:箭头函数

完整写法

let f = (a) => {

    return a+1

}

无参数写法

let f = () => {

    return 1

}

单个参数简写

let f = a => {

  return a+1

}

直接返回运算结果简写

let f = a => a+1

this

除了写法不同,箭头函数和function定义函数的明显区别是this指向。

箭头函数this始终指向定义时所在上下文位置(词法作用域)。

function函数this始终指向调用该函数的对象,即动态作用域。

全局函数

var Obj1 = function(){console.log(this)}
Obj1();  //this 全局调用,this为window  

var Obj2 = () => {console.log(this)}
Obj2();  //this 全局定义,this为window  

对象方法

var obj = {
    f1: () => console.log(this),
    f2: function() {console.log(this)}
}
obj.f1();  // window
obj.f2();  // obj

以上代码可以看到,function函数f2函数由于被obj对象调用,this指向obj对象;箭头函数f1由于在全局定义,其this始终指向window(对象不构成块作用域,所以f1属于全局作用域,详见词法作用域)。

var obj = {
    f1: function(){
        (() => console.log('箭头函数', this))()
    },
    f2: function() {
        (function(){console.log('function函数', this)})()
    }
}
obj.f1();  // 箭头函数     obj
obj.f2();  // function函数  window 

以上代码可以看到,箭头函数定义在f1函数作用域内,其this始终和f1函数指向的同一个对象,即obj对象;function函数尽管定义在f2函数作用域内,其执行时是作为匿名函数被全局调用,使其this最终指向window对象。

构造函数

由于箭头函数this指向其定义时的词法作用域,如果作为构造函数使用,其this无法指向新创建的实例对象,所以箭头函数不能用来定义构造函数。在构造函数内部使用箭头函数其this依然指向其词法作用域。

var Obj1 = function(name){
    (function(name){console.log('func',this); this.name = name})();
}
var obj1 = new Obj1('a');  //this为window  
console.log(obj1);//obj1没有name属性

var Obj2 = function(name){
    (()=>{console.log('(name)=>',this); this.name = name})();
}
var obj2 = new Obj2('a'); //this 为 obj2
console.log(obj2);//obj2.name = 'a'

以上代码可以看到,function函数在构造函数Obj1内部作为匿名函数被全局被调用,this指向window对象;箭头函数作为匿名函数定义在构造函数Obj2内部,其this指向构造函数Obj2的this,由构造函数this指向其被调用时创建的实例对象,这里为obj2,所以箭头函数this指向obj2对象。

call apply

var obj = {a : 1}
var f1 = function(){console.log(this.a)}
var f2 = ()=>{console.log(this.a)} 
f1.call(obj);  //1 
f2.call(obj);  //undefined 

通过call方法使f1函数被obj调用,f1函数的this指向了调用该方法的obj对象,即obj.a = 1;由于f2函数的this始终指向其定义时的词法作用域,即全局作用域,this指向window,call无法改变其this指向。

var obj1 = {
    a : 'obj1'
};
var obj2 = {
    a :  'obj2',
    getA1 : function() {console.log(this.a)}, 
    getA2 : () => {console.log(this.a)} //this指向window
}
obj2.getA1.call(obj1); //obj1 this指向调用该函数的对象 
obj2.getA2.call(obj1);/*undefined*/

通过call方法使getA1函数被obj1调用,getA1函数的this指向了调用该方法的obj1对象,即obj1.a = 'obj1';由于getA2函数的this始终指向其定义时的词法作用域,即全局作用域,this指向window,call无法改变其this指向。

var obj1 = {
  a : 1,
  getA1 : function(p1) {
    var f = function(p2){return p2 + this.a};
    f(p1);
  },
  getA2: function(p1) { 
    var f = p2 => p2 + this.a; //this指向getA2作用域的this
    f(p1);
  }
};
var obj2 = {
  a : 2
}; 
console.log(obj1.getA1(1));         // NaN  即 1 + window.a 
console.log(obj1.getA2(1));         // 2  即 1 + obj1.a = 2
console.log(obj1.getA1.call(obj2,1));// NaN   即 1 + window.a      
console.log(obj1.getA2.call(obj2,1));// 3 即 1 + obj2.a = 3
//getA2中的f方法的this指向getA2的作用域,call方法将getA2的作用域从obj1变为obj2

在上面的代码中,箭头函数由于定义在getA2方法内部,其this始终指向getA2的this,当使用obj1调用getA2方法时,getA2的this指向obj1,所以箭头函数的this也指向obj1,输出2(即 1 + obj1.a ),当通过call使obj2调用getA2方法时,getA2的this指向obj2,所以箭头函数的this也指向obj2,输出2(即 1 + obj2.a );function函数虽然定义在getA1方法内部,但当使用obj1调用getA1方法时,function函数是作为具名函数直接被全局调用的,所以尽管getA1的this指向obj1,function函数的this仍然指向window,最终输出NaN(即 1 + window.a ),当通过call使obj2调用getA1方法时,function函数仍然作为具名函数直接被全局调用,所以getA1的this指向obj2,function函数的this指向window,最终输出NaN(即 1 + window.a )。

箭头函数的this虽然始终指向其定义时指向的对象,call 和 apply(包括 bind)方法不能改变箭头函数的this指向,但是可以通过改变其定义时所指向词法作用域的this对象来改变执行结果。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值