ES6学习笔记:箭头函数

重点写在前面,箭头函数与传统的js函数不同的地方:

  • 没有this,super,arguments,new.target。这些值由箭头函数所属的非箭头函数的相应值来决定。
  • 不能被new调用。 箭头函数没有 [[Construct]] 方法,因此不能被用为构造函数,使用 new 调用箭头函数会抛出错误。
  • 没有原型。传统的js函数都会有原型,但是箭头函数不能被new调用,也不需要原型,也就是没有prototype属性。
  • 不能更改this。箭头函数没有自己的this,this值取的是外部函数的this值,this 的值在函数内部不能被修改,在函数的整个生命周期内其值会保持不变。
  • 没有arguments对象。你必须依赖于具名参数或剩余参数来访问函数的参数。
  • 不允许重复的参数。箭头函数不允许拥有重复的具名参数,而传统函数只在严格模式下才有此要求。

语法

最基本的箭头函数语法:

(参数) => {函数体}

有以下几种不同的写法:

  • 当只有单个参数时,可以直接书写而不需要括号
var add = num =>num+1;
add(2)
  • 如果要传入多个参数,则就需要将他们放在括号中:
var sum = (num1, num2) => num1 + num2;
  • 如果函数没有任何参数,则必须使用一对空括号:
var getName = ()=>"Nicholas";
  • 当函数体只有一个语句时,就可以像前面那样直接书写,不需要花括号,此语句值会被返回
var sum = (num1, num2) => num1 + num2;

// 有效等价于:

var sum = function(num1, num2) {
    return num1 + num2;
};
  • 当函数体包含多个语句时,就需要一对花括号来进行包裹:
var sum = (num1, num2) => {
    console.log("here");
    return num1 + num2;
};
  • 如果想创建一个空函数,则必须使用空的花括号
var doNothing = () => {};
  • 若箭头函数想要从函数体内向外返回一个对象字面量,就必须将该字面量包裹在圆括号内
var getItem = id=>({id:id,name:'jack'})

// 有效等价于:

var getTempItem = function(id) {

    return {
        id: id,
        name: "Temp"
    };
};

将对象字面量包裹在括号内,标示了括号内是一个字面量而不是函数体。

箭头函数也可以用于书写IIFE。
传统的IIFE可能是这样书写:

let person = (function(name){
    return {
        getName:function(){
            return name;
        }
    }
})("jack")

可以使用箭头函数,只要将其包裹在括号中即可:

let person = ((name)=>{
     return {
        getName: function() {
            return name;
        }
    };
})("jack")

需要注意的是括号仅包裹了箭头函数的定义,并未包裹 (“jack”) 。这有别于使用传统函数时的方式——括号既可以连函数定义与参数调用一起包裹,也可以只用于包裹函数定义。

使用传统函数时, (function(){/*函数体*/})();
(function(){/*函数体*/}()); 这两种方式都是可行的。
但若使用箭头函数,则只有下面的写法是有效的: (() => {/*函数体*/})();

没有this绑定

箭头函数没有 this 绑定,意味着箭头函数内部的 this 值只能通过查找作用域链来确定。

  • 如果箭头函数被包含在一个非箭头函数内,那么 this 值就会与该函数的相等;
  • 否则, this 值就会是全局对象

在不使用箭头函数的时候,this的取值可能会引起一些混乱:

var PageHandler = {

    init: function() {
        document.addEventListener("click", function(event) {
            this.doSomething(event.type);    
        }, false);
    },

    doSomething: function(type) {
        console.log("Handling " + type );
    }
};

我们为click事件绑定了事件处理函数,但是真正在click事件发生时,this的值却不是pageHandler对象,而是点击的对象,此时调用this.doSomething会出错。
为了修改这个错误,我们会在定义事件处理函数的时候强制绑定当前对象:

var PageHandler = {

    init: function() {
        document.addEventListener("click", (function(event) {
            this.doSomething(event.type);    
        }).bind(this), false);
    },

    doSomething: function(type) {
        console.log("Handling " + type );
    }
};

现在此代码能像预期那样运行.

现在我们可以使用箭头函数优雅地做到这件事:

var PageHandler = {

    init: function() {
        document.addEventListener("click", event=>{
            this.doSomething(event.type);    
        }, false);
    },

    doSomething: function(type) {
        console.log("Handling " + type );
    }
};

事件处理函数改写成了箭头函数,由于箭头函数没有自己的this,因此它的this值和外层函数init()相同,即为对象pageHandler,这样无论在什么情况下this都拥有正确的指向。

同样,由于箭头函数的 this 值由包含它的函数决定,因此不能使用 call() 、 apply() 或 bind() 方法来改变其 this 值。

箭头函数与数组

箭头函数的简洁语法也让它成为进行数组操作的理想选择。

例如,若你想使用自定义比较器来对数组进行排序,通常会这么写:

values.sort(function(a,b){
    return a-b;
})

使用箭头函数可以使代码更简洁:

values.sort((a,b)=>a-b);

能使用回调函数的数组方法(例如 sort() 、 map() 与 reduce() 方法),都能从箭头函数的简洁语法中获得收益,它将看似复杂的需求转换为简单的代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值