[原创] 码路工人

大家好,这里是码路工人有力量,我是码路工人,你们是力量。


如果没用过CSharp的lambda 表达式,也没有了解过ES6,那第一眼看到这样代码什么感觉?

/* eg.0
* function definition
*/ var arr = [1,2,3,5,8,13,21] arr.forEach(n => console.log(n))

数组的forEach 方法里需要传入一个函数(没用过 CSharp 里委托 delegate 的也许会觉得奇怪,js 里参数竟然可以是一个方法,其实 C# 里也是早就有的),这n =>是什么鬼?

这是今天要说的主角,箭头函数Arrow Function。

#注:

  • C# 中操作集合的各种 lambda 表达式其实就是一个个简短的匿名函数,
  • ES6的箭头函数就可以理解为 C# 中的 lambda 表达式式的东西,
  • Python 中同样也是有 lambda 表达式的(当时用的时候有限定,只能写一句),
  • 只是不同语言间写法或语法不同,所以我有个观点就是:
  • 认真学一门语言,不只停留在入门,不能说精通也要达到进阶,
  • 再去学其它的,就会发现编程语言是相通的,编程思想更是相通的
  • 码工我不是搞 Java 的,但是会 C# 的看起 Java 代码也是不太费劲,因为真的很像

    => Java 里也有 lambda 。

1. Arrow Function 的基本用法

1.1 本质就是匿名函数

  普通定义一个函数,要用到function 关键字,不管是存在提升现象的function foo() { } 还是定义给变量var foo = function() { } ,这样的话调用时才能找到这个函数,就像每个人都有名字一样。

  匿名函数就不一样了,它没有名字,因此只能在定义它的位置调用(这么说不严谨,但不影响理解,具体见下文)。所以,用箭头函数去定义一个单独函数而不调用不执行,是没有意义的。当然能这么写,js本身不会报错。

  除了定义时的区别,匿名函数使用时,跟普通函数还是相似的,要么定义给一个变量,要么直接当作回调函数写在参数位置。

  因为本身就没有function 关键字和方法名,也就无法像ES5里那样定义类/构造函数。不可能也没理由这样用。如果 "var Foo = () => { }" 这样写,也不能当作类/构造函数,"new Foo()" 的时候会报错。毕竟用ES6的话也不会这样定义类。(用class 跟constructor)

/* eg.1
* function definition
*/ //------------------------------------------------- function logParam(param) {
console.log(param)
} logParam("foo") // foo //------------------------------------------------- // Should not define a funtion using arrow-function itself
// because no function name to call and will not execute
(param) => console.log(param) const foo = (param) => console.log(param)
foo("bar") // bar //-------------------------------------------------

1.2 基本使用特点

  • 普通的正常写法

    /* eg.2
    * arrow function
    */ //-------------------------------------------------
    var arr = [1,2,3,5,8,13,21] // Normal:
    console.log(arr.map(function(item, index) {
    return `No.${index}: ${item}`
    }))
    //["No.0: 1", "No.1: 2", "No.2: 3", "No.3: 5", "No.4: 8", "No.5: 13", "No.6: 21"] // Use arrow function:
    console.log(arr.map((item, index) => {
    return `No.${index}: ${item}`
    }))
    //["No.0: 1", "No.1: 2", "No.2: 3", "No.3: 5", "No.4: 8", "No.5: 13", "No.6: 21"]
    //-------------------------------------------------

    最直观的一点就是写法上稍微简易了一丢丢。它基本的特点就是简易了,继续往下看。

  • 只有一个参数时,参数括号 可省略

    /* eg.2
    * arrow function
    */ //-------------------------------------------------
    var arr = [1,2,3,5,8,13,21] // Normal:
    arr.forEach(function(item) {
    console.log("当前元素:" + item)
    }) // Use arrow function:
    arr.forEach( item => {
    console.log("当前元素:" + item)
    })
    //-------------------------------------------------

    以上例子中只有一个item参数,所以参数括号省略了也能正常执行。

  • 方法体只有一句 { return expression } 时,花括号跟 return 可省略

    当然,如果本身就没有做return也是可以只省略花括号的,没有返回值处理时默认就是返回undefined。

    /* eg.3
    * arrow function
    */
    //------------------------------------------------- var arr = [1,2,3,5,8,13,21] // Normal:
    arr.forEach(function(item){
    console.log("当前元素:" + item)
    })
    console.log(arr.map(function(item,index){
    return `No.${index}: ${item}`
    })) // Use arrow function:
    arr.foreach((item,index) => console.log(`No.${index}: ${item}`))
    console.log(arr.map((item,index) => `No.${index}: ${item}` )) //-------------------------------------------------

    以上例子中分别演示了无return与有return时箭头函数中的简便写法。

    执行结果可以在 chrome 浏览器下的 console 里查看(F12打开开发者模式)。

1.3 补充:没有参数时

  没有参数的情况也是有的,可以跟普通函数一样,空括号就可以了。另外,还有一种约定俗成的写法:_ 。如下:

/* eg.4
* arrow function: no-param
*/ //-------------------------------------------------
const foo = () => "bar"
const foo = _ => "bar" // as same as ↓
const foo = function () {
return "bar"
}

2. 其它特点

2.1 this 指向的问题

  箭头函数用起来感觉轻便了许多,但也有不少问题。其中主要、最经常遇到的可能就是this指向问题了。

/* eg.5
* arrow function: this
*/
//------------------------------------------------- const person = {
name: "Coder Power",
greet1: function() {
console.log(this)
console.log("Hello!I am " + this.name + ".")
},
greet2: () => {
console.log(this)
console.log("Hello!I am " + this.name + ".")
}
} // 'this' in normal function
// is object person
person.greet1() // 'this' in arrow function
// is object window
person.greet2() //-------------------------------------------------

  以上代码例子中,greet1中this指向为person对象。这一点非常好理解,以外 js 中的 this 是谁调用,指向谁。

  而greet2中的this却指向了 window对象。怎么会这样?

  其实码工刚开始也没弄明白,只是知道 this 不一样。后来仔细想了想,箭头函数里的 this 为定义函数时它外部函数里的 this ,也就时在 person 定义中,这时的 this 就是 window。(window.person)

  • 箭头函数this总结

    => 函数没有自己的this

    => 函数里的this 是父级作用域里的this

    => 函数不能通过apply/call 的方式绑定this

    /* eg.6
    * arrow function: this
    */
    //------------------------------------------------- // can not change 'this' in arrow function
    // by apply/call
    person.greet2.call(person)
    person.greet2.apply(person)
    // ↑"this.name" will still be undefined
    //-------------------------------------------------

    所以在需要用到this 的方法中要慎重。

2.2 ES6箭头函数的其它特点

  在前文 1.1 中我们就说了,箭头函数定义出来的函数变量不能通过new 来实例化出一个对象。

它跟继承扯不上关系,不能做构造函数,也没有原型(prototype)。获取参数也仅限与方法调用传参,不能用arguments来取。

ES6箭头函数中没有以下属性/对象:

  • 箭头函数不能new

  • 箭头函数没有prototype

  • 箭头函数没有super

    上一篇中介绍了 ES5 及 ES6 里的类与继承,其中 ES6 里子类的构造函数里必须先调用一次super 也就是父类的构造函数,才生成了实例对象this 。而箭头函数是没有super 的。

  • 箭头函数没有arguments

  • 箭头函数没有new.target (本来就不能 new ,就更没有 new.target 了)

    上述这些相对不常用或说在使用箭头函数时相关性较小,箭头函数本意是简化书写,更多的是用在填写一个普通的回调函数上。


读到这里,对于 JavaScript/ES6 里箭头函数 Arrow Function 的使用方法就掌握差不多了吧。

思考一下,哪些场景下适合/不适合用箭头函数呢?可以评论区留个言再走啊~

希望对你能有帮助,下篇再见。


欢迎关注分享,一起学习提高吧。

QRCode/微信订阅号二维码


[ES6系列-02]Arrow Function:Whats this?(箭头函数及它的this及其它)的更多相关文章

  1. ES6躬行记(15)——箭头函数和尾调用优化

    一.箭头函数 箭头函数(Arrow Function)是ES6提供的一个很实用的新功能,与普通函数相比,不但在语法上更为简洁,而且在使用时也有更多注意点,下面列出了其中的三点: (1)由于不能作为构造 ...

  2. ES6学习总结一(变量;箭头函数;解构赋值)

    一.变量 var  1 可以重复声明(var a=1;var a=7;)(一开始用着会觉得限制很少,但是在大型项目会麻烦,人多嘴杂的时候定义重复了就容易出问题还不好找) 2 无法限制修改 3 没有块级 ...

  3. es6笔记 day2---函数默认参数、箭头函数、剩余参数

    函数变化: 1.函数默认参数 2.函数参数默认是已经定义了,不能再使用let.const声明 3.扩展运算符.rest运算符 ...就是扩展运算符,它的作用就是把数组给展开 结合函数使用传参,也可以将 ...

  4. [ES6系列-07]Generator Function: 生成器函数

    [原创]码路工人 Coder-Power 大家好,这里是码路工人有力量,我是码路工人,你们是力量. github-pages 博客园cnblogs Generator function 生成器函数是E ...

  5. ES6系列之箭头函数

    本系列是在平时阅读.学习.实际项目中有关于es6中的新特性.用发的简单总结,目的是记录以备日后温习:本系列预计包含let/const.箭头函数.解构.常用新增方法.Symbol.Set&Map ...

  6. [译]ES6箭头函数和它的作用域

    原文来自我的前端博客: http://www.hacke2.cn/arrow-functions-and-their-scope/ 在ES6很多很棒的新特性中, 箭头函数 (或者大箭头函数)就是其中值 ...

  7. ES6箭头函数和它的作用域

    原文来自我的前端博客: http://www.hacke2.cn/arrow-functions-and-their-scope/ http://es6rocks.com/2014/10/arrow- ...

  8. ES6系列之解构

    本系列是在平时阅读.学习.实际项目中有关于es6中的新特性.用发的简单总结,目的是记录以备日后温习:本系列预计包含let/const.箭头函数.解构.常用新增方法.Symbol.Set&Map ...

  9. ES6系列之let/const及块级作用域

    本系列是在平时阅读.学习.实际项目中有关于es6中的新特性.用发的简单总结,目的是记录以备日后温习:本系列预计包含let/const.箭头函数.解构.常用新增方法.Symbol.Set&Map ...

随机推荐

  1. 图论--2-SAT--HDOJ/HDU 1824 Let's go home

    Problem Description 小时候,乡愁是一枚小小的邮票,我在这头,母亲在那头.                         -- 余光中 集训是辛苦的,道路是坎坷的,休息还是必须的. ...

  2. codeforce 272B Dima and Sequence

    B. Dima and Sequence Dima got into number sequences. Now he's got sequence a1, a2, ..., an, consisti ...

  3. unittest(封装用例)

    from selenium import webdriver from time import sleep import unittest #导入unittest库 import HTMLTestRu ...

  4. Spring 注解注入—@Qualifier 注释

    当创建多个具有相同类型的 bean 时,并且想要用一个属性只为它们其中的一个进行装配,在这种情况下,你可以使用 @Qualifier 注释和 @Autowired 注释通过指定哪一个真正的 bean ...

  5. 一只简单的网络爬虫(基于linux C/C++)————主事件流程

    该爬虫的主事件流程大致如下: 1.获取命令行参数,执行相应操作 2.读取配置文件,解析得到各种设置 3.载入各种模块 4.种子入队,开启DNS解析线程(原始队列不为空时解析) 5.创建epoll,开启 ...

  6. spring bootweb综合开发的整理

    1.json接口开发 当前开发中微服务的概念日渐深入人心,所以json数据交互可以带来的便利也不言而喻.在springboot中json数据的返回方式比较简单,只需要用@RestController注 ...

  7. OSG程序设计之Hello World 3.0

    直接上代码: #include <osgDB/ReadFile> #include <osgViewer/Viewer> #include <osgViewer/View ...

  8. 软件——IDEA主题美化

    前言 IntelliJ IDEA主要用于支持 Java.Scala.Groovy 等语言的开发工具,同时具备支持目前主流的技术和框架,擅长于企业应用.移动应用和 Web 应用的开发. IntelliJ ...

  9. N - 寿司晚宴 HYSBZ - 4197 状压dp

    N - 寿司晚宴 HYSBZ - 4197 推荐题解 这个题目我觉得还是很难的,借助题解写出来的,题解还看了很久,现在还是不是很理解. 首先这个数比较大有500,如果直接就像这个题目S - Query ...

  10. js中刷新页面的方式总结

    1.window.onload / document.onload 2.history.go(num): (1)num为参数,num为正表示前进几个页面,类似于history.forward(): ( ...