• 箭头函数的基本用法与特点
  • 函数与ES6新语法

一、箭头函数的基本用法与特点

  • 声明箭头函数采用声明变量和常量的关键字:var、let、const
  • 箭头函数的参数:没有参数用"()"空括号表示、一个参数可以不写括号、多个参数用"(a,b,c)"括号包裹
  • 使用箭头“=>”连接参数与执行块"{}"。
  • 如果执行块内只有return语句,可以不写大括号“{}”和return关键字。
 //ES6箭头函数
const foo = (x,y) => x + y;
//ES5编译结果
var foo = function foo(x, y) {
return x + y;
};

箭头函数的特点

  • 不写function关键字
  • 只能作为函数使用,不能使用nwe构建对象,因为没有Function原型
  • 箭头函数的参数不能重复名
  • 内部arguments、this由定义时外围最近一层的非箭头函数的arguments和this决定值

这里我暂时先不解析箭头函数的特点,而是要说明一点,虽然箭头函数语法被称赞简洁、清晰明了、可读性强,真的如此?先来看下面这个示例:

 //ES6的一个箭头函数示例
var dollabillsyall = (strings, ...values) =>
strings.reduce( (s, v, idx) => {
if(idx > 0){
if(idx > 0){
if(typeof values[idx - 1] == "number"){
s += `$${values[idx - 1].toFixed(2)}`;
}else{
s += values[idx - 1];
}
}
return s + v;
}
},"");
//ES5的编译结果
var dollabillsyall = function dollabillsyall(strings) {
for (var _len = arguments.length, values = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
values[_key - 1] = arguments[_key];
} return strings.reduce(function (s, v, idx) {
if (idx > 0) {
if (idx > 0) {
if (typeof values[idx - 1] == "number") {
s += "$".concat(values[idx - 1].toFixed(2));
} else {
s += values[idx - 1];
}
} return s + v;
}
}, "");
};

当你看到上面这个示例后你还会觉得箭头函数简洁、清晰明了吗?从代码解构上来说明显可以感觉到编译成ES5反而更清晰。所以箭头函数的简洁、清晰明了、可读性强是有前提的,就是函数比较简短的情况下才能体现出箭头函数的优势。千万不要一味的追求新语法而不作选择的修改代码的编写方式,这明显是不明智的行为。

1.1箭头函数不能被当作构造函数来使用:

 let foo = () => {
this.a = 10;
}
new foo();//foo is not a constructor :foo不是一个构造函数

1.2全局作用域下的箭头函数没有arguments:

 let sum = () =>{
console.log(arguments);
}
sum();//ReferenceError: arguments is not defined at sum :arguments没有定义

1.3全局作用域下的箭头函数的this指向window(非严格模式下):

 //ES6全局作用域下的箭头函数this的指向
var foo = () => {
console.log(this);
}
foo(); //window --不使用babel编译的执行结果
//ES5的编译的结果
"use strict";
var _this = void 0;
var foo = function foo() {
console.log(_this);
};
foo(); //undefined--这是因为严格模式下函数自执行this指向undefined

1.4前面两个示例都印证了箭头函数的arguments、this在定义时由外围的最近一层非箭头函数的arguments和this决定,所以在全局上没有arguments和全局函数的this指向window。按照这个说法,如果声明一个对象,然后对象的属性引用了全局定义的函数,采用对象引用执行其this也是指向window。这个毫无疑问,的确时这样,请看示例:

 var a = 'outerObj';
var foo = () => {
console.log(this.a);
}
let obj = {
a: 'innerObj',
fn:foo
}
obj.fn();//outerObj : obj.fn引用的时全局的foo箭头函数,其this是定义是就确定的

1.5一定请注意前面的定义,箭头函数的this和arguments由定义时的最近的非箭头函数的arguments和this决定,所以即便在全局的对象上直接写到对象上的箭头函数,其this指向也是window。

 var a = 'outerObj';
let obj = {
a: 'innerObj',
fn:()=>{
console.log(this.a);
}
}
obj.fn();//outerObj : obj是全局对象,obj.fn是箭头函数,所以其this指向了widnow

1.6前面所证明的还是只箭头函数的外层没有函数的情况(全局箭头函数、引用执行全局箭头函数、全局对象上定义的箭头函数),其this指向都是window,接着来看这个示例,证明箭头函数的this指向外层最近的非箭头函数的this。

 var a = 'outerObj';
var obj = {
a:"innerObj",
fn(){
return () => {
console.log(this.a);
}
}
}
var obj1 = {
a:"strObj1"
}
var foo = obj.fn();
obj1.foo = obj.fn();
foo(); //innerObj
obj1.foo(); //innerObj

1.7使用箭头函数修正异步函数执行的this指向(以定时器为例):

 //使用箭头函数的this指向特性修正异步函数执行的this指向
var obj = {
a:"innerObj",
fn(){
setTimeout(() => {
console.log(this.a);
},1000);
}
}
obj.fn(); //innerObj
//ES5中的编译结果(也是我们之前解决异步函数执行this指向的常用方法)
var obj = {
a: "innerObj",
fn: function fn() {
var _this = this; //变量缓存this setTimeout(function () {
console.log(_this.a); //通过函数的作用找到缓存this的变量
}, 1000);
}
};
obj.fn();

关于箭头函数使用的小总结:

  • 函数中只有唯一语句return某个计算出的值,适应箭头函数;
  • 函数内部没有this引用,且没有自生引用(递归、事件绑定、解除绑定),适应箭头函数;(this引用可以用来特殊处理this指向,灵活应用)
  • 如果内层函数表达式依赖封装函数中某种像var args = Array.prototype.slice.call(arguments)来保证arguments的词法复制,那么这个内层函数应该可以安全地使用箭头函数。
  • 函数声明、较长的多语句函数表达式、需要词法名称标识(递归等)的函数,以及任何不符合以上几个特征的函数——尽量避免使用箭头函数。

二、函数与ES6新语法

2.1箭头函数省略return关键字和{}不能适应返回一个对象字面量的值:

 //ES6箭头函数返回对象字面量值(错误代码)
let sum = (a, b) => {a:a, b:b};
//被识别成下面这段代码(错误代码)
let sum = (a, b) => {
a:a, b:b;
return undefined;
};
//解决方法就是将返回的对象字面量变成一个表达式(正确代码)
let sum = (a, b) => ({a:a, b:b});

2.2使用箭头函数改善高级函数的结构:

 //ES5高级函数的场景示例
function foo(x){
return function(y){
return function(z){
return x + y + z;
}
}
}
console.log(foo(1)(2)(3));//
//ES6应用箭头函数简化高级函数结构
let foo = x => y => x => x + y +z;
console.log(foo(1)(2)(3));//

2.3默认参数的函数的参数长度--背后说明的默认参数的底层实际是在执行时向arguments上添加的数据:

 console.log((function (a){}).length);//
console.log((function (b=5){}).length);//
console.log((function (a,b,c=10){}).length);//

2.4匿名函数的名称在ES5与ES6中的差异,ES5的name属性不会返回匿名函数所属的变量名称(函数名),而在ES6中则是返回函数所属的变量名称(函数名)看下面的示例。对于具名函数无论被赋值于谁,在ES5和ES6中都是返回具名函数原始的函数声明名称。

 var f = function(){}
//ES5
f.name //"",空字符串
//ES6
f.name //"f",函数名

ES6入门五:箭头函数、函数与ES6新语法的更多相关文章

  1. 【第五篇】SAP ABAP7.5x新语法之命名规约

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:SAP ABAP7.5x系列之命名规约   命名 ...

  2. TypeScript入门三:TypeScript函数类型

    TypeScript函数类型 TypeScript函数的参数 TypeScript函数的this与箭头函数 TypeScript函数重载 一.TypeScript函数类型 在上一篇博客中已经对声明Ty ...

  3. es6入门3--箭头函数与形参等属性的拓展

    对函数拓展兴趣更大一点,优先看,前面字符串后面再说,那些API居多,会使用能记住部分就好. 一.函数参数可以使用默认值 1.默认值生效条件 在变量的解构赋值就提到了,函数参数可以使用默认值了.正常我们 ...

  4. ES6快速入门(一)函数与作用域

    ES6快速入门 一.块级绑定 1.var声明与变量提升 使用var声明的变量,不论在何处都会被视为(声明)在函数级作用域顶部的位置发生. function getValue(condition) { ...

  5. ES6 入门系列 - 函数的扩展

    1函数参数的默认值 基本用法 在ES6之前,不能直接为函数的参数指定默认值,只能采用变通的方法. function log(x, y) { y = y || 'World'; console.log( ...

  6. [js高手之路] es6系列教程 - 箭头函数详解

    箭头函数是es6新增的非常有意思的特性,初次写起来,可能会觉得别扭,习惯之后,会发现很精简. 什么是箭头函数? 箭头函数是一种使用箭头( => )定义函数的新语法, 主要有以下特性: 不能通过n ...

  7. 前端项目中常用es6知识总结 -- 箭头函数及this指向、尾调用优化

    项目开发中一些常用的es6知识,主要是为以后分享小程序开发.node+koa项目开发以及vueSSR(vue服务端渲染)做个前置铺垫. 项目开发常用es6介绍 1.块级作用域 let const 2. ...

  8. ES6系列之箭头函数

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

  9. ES6入门——函数的扩展

    1.函数参数的默认值 在ES6之前,不能直接为函数的参数指定默认值,只能采用变通的方法.现在ES6可以为函数的参数添加默认值,简洁了许多. ES5 function show(a,b){ b = b ...

随机推荐

  1. 2.基于AOP自定义注解Annotation的实现

    上一篇中分析了AOP的实现原理, 总结为: 判断对象是否需要被代理?@Aspect注解的实现是根据切入点表达式 代理之后需要做什么,就是那些通知,本质上是实现了MethodInterceptor的拦截 ...

  2. leetcode25 K 个一组翻转链表

    这道题关于链表的操作,中间指针操作略复杂. /** * Definition for singly-linked list. * struct ListNode { * int val; * List ...

  3. 异步模型 requestAnimationFrame

    异步模型 requestAnimationFrame 前言 window.requestAnimationFrame() 告诉浏览器--你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函 ...

  4. python3使用tkinter之Menu坑

    添加菜单之后,下拉菜单的第一行是一条虚线,点击会在窗口的左上角独立显示下拉菜单,如下图所示: 去掉的方法是:创建文件菜单的时候,添加 tearoff=0参数 tearoff 有 0 和 1 两个值,分 ...

  5. lua学习笔记1--基础语法

    print("打印日志");--单行注释 --[[ 多行注释 --]] a = --变量的类型,是由变量储存的数据决定 数据类型: number:数值类型,可以存储整数和小数 bo ...

  6. Leetcode之101. Symmetric Tree Easy

    Leetcode 101. Symmetric Tree Easy Given a binary tree, check whether it is a mirror of itself (ie, s ...

  7. 架构模式: 服务前端的后端(BFF模式)

    架构模式: 服务前端的后端(BFF模式) 上下文 让我们假设您正在构建一个使用Microservice体系结构模式的在线商店,并且您正在实现产品详细信息页面.您需要开发产品详细信息用户界面的多个版本: ...

  8. DP————最小覆盖问题

    原题:https://www.luogu.org/problem/P2279 题解转载自:https://www.luogu.org/blog/contributation/solution-p227 ...

  9. 【计算机视觉】Vibe Vibe+

    ViBe是一种像素级的背景建模.前景检测算法,该算法主要不同之处是背景模型的更新策略,随机选择需要替换的像素的样本,随机选择邻域像素进行更新.在无法确定像素变化的模型时,随机的更新策略,在一定程度上可 ...

  10. 【VS开发】C++ opencv Mat基础

    OpenCV2:Mat 1.Mat基础 在计算机内存中,数字图像是已矩阵的形式保存的.OpenCV2中,数据结构Mat是保存图像像素信息的矩阵,它主要包含两部分:矩阵头和一个指向像素数据的矩阵指针. ...