资讯专栏INFORMATION COLUMN

ES6-箭头函数

wapeyang / 1984人阅读

摘要:编程中经常定义一些短小的匿名函数,使用箭头函数语法可使得这类函数的定义更加简洁。外部函数的,等价于定义个局部变量修改内部的所以这样,,也就无法修改箭头函数的值的。抛异常即箭头函数不能作为构造函数,其也不具有属性。

一、概述

箭头函数是指通过=>语法定义的函数。JS编程中经常定义一些短小的匿名函数,使用箭头函数语法可使得这类函数的定义更加简洁。

// ES3/5方式
var fun1 = function(x, y) {
    return x + y;
}

var arr1 = [1,2,3].map(function(item){
    return item * item;
})

// 箭头函数方式
var fun2 = (x, y) => x + y;

var arr2 = [1,2,3].map((item) => item * item)

少些了不少代码,看着也简洁许多,有木有。

二、语法

一般的语法格式:

(param1, param2, …, paramN) => { 语句 } 

注意参数部分和箭头=>之间不能换行,如:

// 正确
var add1 = (x, y) => x + y; 

// 正确
var add2 = (x,             
    y) => x + y;
    
// 正确(=>后面不会自动插入分号的)
var add3 = (x, y) => 
x + y;

// 语法错误 Uncaught SyntaxError: Unexpected token =>
var add4 = (x, y) 
    => x + y;

 // 语法错误 Uncaught SyntaxError: Unexpected token =>
var add5= x 
    => x + 2;

上例中add4定义会报错,原因在解析的时候(x, y)后面会自动插入分号,所以当解析=>时就报错了。

如果花括号里只包含一个return语句,则可以简写为:

(param1, param2, …, paramN) => 表达式 // 等价于 => { return 表达式; } 

因为对象字面量也是用花括号表示的,所以当表达式是个对象字面量时需要用括号包住:

var a = p => ({a: p}) // 不能写成:p => {a: p}

如果有且只有一个形参,则可以省略括号,简写为:

param => {语句} // 等价于 (param) => {语句} 

如上例中的fun1定义:

var fun1 = (x, y) => x + y;
// 等价于
var fun1 = (x, y) => { return x + y; }
三、特性

箭头函数不仅仅更方便定义匿名函数,它还具有一些特性,这些使得箭头函数在使用上也更方便。
箭头函数一般定义在一个函数内部,箭头函数的函数体内是可以访问外部函数定义的局部变量的(闭包),但是外部函数还有两个特殊的变量:this和arguments。因为每个函数都具有自己的this和arguments变量,所以当内部函数访问外部函数这两个变量时,我们一般采用这种方式:

var outer = {
    name: "outer",
    say: function() {
        var _arguments = arguments, // 先把arguments赋值给局部变量_arguments 
            _this = this; // 先把this赋值给局部变量_this
        
        function inner() {
            console.log(arguments.length); // 内部函数的arguments
            console.log(_arguments.length); // 通过局部变量_arguments访问外部函数的arguments变量
            
            console.log(this.name); // 内部函数的this
            console.log(_this.name); // 通过局部变量_this访问外部函数的this变量
        }
        
        return inner;
    }
}

但是箭头函数体可以直接访问外部函数的this和arguments变量!!!逆天啊。

3.1 箭头函数“不具有自己的this变量” 1 特性语法

箭头函数体内this变量指向外部函数的this。如上例可以写为:

var outer = {
    name: "outer",
    say: function() {
        return () => { console.log(this.name); } // 外部函数outer的this,
    }
}

并且通过call,apply,bind函数也是无法修改箭头函数的this变量的。

var outer = {
    name: "outer",
    say: function() {
        var inner = () => { console.log(this.name); } // 依旧外部函数outer的this,
        return inner.bind({name: "inner"}) //
    }
}
2 特性原理

箭头函数并不是真的不具有自己的this变量,只是它重新修改this变量的值。

var outer = {
    name: "outer",
    say: function() {
        return () => { console.log(this.name); } // 外部函数outer的this,
    }
}

// 等价于:
var outer = {
    name: "outer",
    say: function say() {
        var _this = this; // 定义个局部变量_this
        return function () {
            this = _this; // 修改内部的this
            console.log(this.name);
        };
    }
};

所以这样call,apply,bind也就无法修改箭头函数的this值的。

3.2 箭头函数“不具有自己的arguments变量”

跟this变量类似箭头函数也“不具有自己的arguments变量”,原理跟this类似。

总结一句话:箭头函数是为了特殊的使用场景(即更方便的定义和使用匿名函数),它的这些特性也是为了方便其使用。

四、使用限制 4.1 不能用new 操作符

对箭头函数使用new操作符会抛TypeError异常。

var A = () => {}
var a = new A(); //抛异常 Uncaught TypeError: A is not a constructor

即箭头函数不能作为构造函数,其也不具有prototype属性。原因应该是其内部的this变量被重写了,不能作为构造函数理所当然。但是箭头函数也是函数:

var a = () => {};
console.log(a instanceof Function); // true

总结一句话:箭头函数是不能作为构造函数的特殊函数。

4.2 跟其他运算符一起用

箭头函数=>不是运算符,当箭头函数作为右值跟其他运算符一起运算操作时其具有特殊的解析顺序

function func(callback) {
    // 一般函数方式
    callback = callback || function() {} // 没问题
    // 报错了,语法错误:Uncaught SyntaxError: Unexpected token )
    callback = callback || () => {};
    // 这样写就对了
    callback = callback || (() => {});
}

总结一句话:箭头函数虽然不是运算符,但其写法和解析有点像运算符的操作。当箭头函数作为右值参与其他运算符的运算时记得加上括号。

4.3 需要使用自己this的函数

箭头函数"没有自己的this",所以它不适用那些需要使用自己this的场景(如成员方法,事件回调函数等)

// 成员方法
var outer = {
    name: "outer",
    say: () => { 
        // 这里的this不是outer,但是我们期望在成员方法的this应该指向对象本身
        console.log(this.name);  
    }
}

// 事件处理函数
document.getElementById("test").onclick = function() {
  console.log(this); // 这里的this不是触发事件的DOM对象
}

总结一句话:箭头函数虽然写起了比较爽,但不能滥用,它是有特殊应用场景的。要懂得什么时候不该用。

参考

MDN 箭头函数

w3cPlus ES6学习笔记:箭头函数

JavaScript 语句后应该加分号么?

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/96284.html

相关文章

  • es6 - 箭头函数

    摘要:也就是说箭头函数的的值不再根据调用时上下文确定,而是像普通变量那样根据定义时的作用域链进行查找。箭头函数中的依然要根据定义时的作用域链进行查找。知乎这篇文章对箭头函数的一些不适合的场景进行了总结,可以作为参考。 es6 - 箭头函数 哇,箭头函数...,听起来好NB,但是如果你知道它是因为使用了=>这样类似箭头的符号 ,所以才叫箭头函数。 瞬间感觉:呵,这名字起的...。 es6增加了...

    13651657101 评论0 收藏0
  • ES6学习笔记之箭头函数

    摘要:特性介绍箭头函数是新增的特性之一,它为这门语言提供了一种全新的书写函数的语法。用生成的函数会定义一个自己的,而箭头函数没有自己的,而是会和上一层的作用域共享。 本文同步自我得博客:http://www.joeray61.com JS中的箭头 箭头在JS里并不算是个新鲜的玩意儿,一直以来,JS都支持-->这样的箭头。 很早的时候有些浏览器还不支持JS,当时的人们为了兼容这些浏览器,需要这...

    Vultr 评论0 收藏0
  • 深入ES6箭头函数

    摘要:令人震惊的箭头函数引入了写入函数的新语法。使用箭头函数创建简单对象时有一个警告。代码因此被默默地解释为一个不执行任何操作并返回未定义的箭头函数。内部函数是一个箭头函数,所以它从封闭范围继承此函数。 箭头从一开始就一直是JavaScript的一部分。第一个JavaScript教程建议在HTML注释中包装内联脚本。这会阻止不支持JS的浏览器错误地将JS代码显示为文本。你会写这样的东西: ...

    MasonEast 评论0 收藏0
  • ES6 箭头函数 从了解到深入

    摘要:有传闻说,箭头函数的语法,是受到了的影响,并且它与中的语法一样,共享上下文。箭头函数是新增加的一个特性。箭头函数没有自己的值,其值是通过继承其它传入对象而获得的通常来说是上一级外部函数的的指向。 箭头函数 1. 简单的定义: 胖箭头函数 Fat arrow functions,又称箭头函数,是一个来自ECMAScript 2015(又称ES6)的全新特性。有传闻说,箭头函数的语法=>,...

    Eminjannn 评论0 收藏0
  • ES6~你跟箭头函数升华之路

    摘要:箭头函数简单的定义胖箭头函数,又称箭头函数,是一个来自又称的全新特性。箭头函数是新增加的一个特性。使用箭头函数的注意点箭头函数在参数和箭头之间不能换行。值得注意的一点就是对象的指向是可变的,但在箭头函数内是固定的。 箭头函数 1. 简单的定义: 胖箭头函数 Fat arrow functions,又称箭头函数,是一个来自ECMAScript 2015(又称ES6)的全新特性。有传闻说,...

    Faremax 评论0 收藏0
  • 关于ES6箭头函数的this问题

    摘要:对象的指向是可变的,但是在箭头函数中,它是固定的。同样的由于箭头函数没有自己的所以传统的显性绑定无效内部的指向外部在的学习中,的指向问题一直是个难点,特别是在对象方法中使用时,必须更加小心。由此箭头函数在很大程度上减少了我们的困扰。 什么是箭头函数 用法 ES6 允许使用箭头(=>)定义函数 测试 var p1 = document.getElementById(test1)...

    LeviDing 评论0 收藏0

发表评论

0条评论

wapeyang

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<