ECMAScript6(ES6)标准之函数扩展特性箭头函数、Rest参数及展开操作符_箭头函数不传参-程序员宅基地

技术标签: 扩展  ecmascript6  标准  Web前端  JavaScript-ES6  JavaScript  函数  

tip:有问题或者需要大厂内推的+我脉脉哦:丛培森 ٩( ‘ω’ )و

ES6扩展了很多语法糖语法
其中对于函数我们又可以使用一种叫做“箭头函数”的写法
同时引入了Rest参数
利用“…”可以获取多余参数
这样就我们就不要使用arguments对象了
下面我来详细地谈一谈

#函数默认参数
ES6没有出现之前
面对默认参数会让很多人感到痛苦
大家会采用各种hack
比如:arr = arr || []
现在要容易得多

function foo(name = 'payen'){
    console.log('my name is ' + name);
}
foo(); //my name is payen

只需要在参数列表中像赋值一样
就可以使用默认参数
#Rest参数
当一个函数的最后一个参数有“…”这样的前缀
它就会变成一个参数的数组
为了让大家更好的理解
先来回忆一下我们以前ES6之前使用的arguments

function foo(){
    var args = Array.prototype.slice.call(arguments);
    console.log(args);
}
foo(1, 2, 3);// [1, 2, 3]

这里我先使用Array原型上的slice把arguments类数组
变成了真正的数组
然后打印这个参数数组
现在我们使用ES6的Rest参数
代码可已修改为这样

function foo(...args){
    console.log(args);
}
foo(1, 2, 3);// [1, 2, 3]

确实要简洁很多
注意Rest参数与arguments有以下几点区别

  • Rest参数是未指定变量名的参数数组
    arguments是全部参数的集合
  • Rest参数是真正的数组
    arguments对象只是有length属性的类数组

#展开操作符
上面我们提到了“…”操作符
包括我之前写到的解构赋值语法
都用到了它
它是ES6的新特性
然而它的强大不只如此
“…”叫做展开操作符
允许一个表达式在某处展开,用于
存在多个参数(函数调用)、多个元素(数组)、多个变量(解构赋值)
下面我就把除了Rest参数以外的用法总结一下
(解构赋值的应用也不谈了,忘了的同学戳这里:传送门,目录下的“1.3特殊用法”)
##函数调用
想一想我们在ES6之前
如何将数组拆分作为参数传入函数

var arr = [1, 2, 3];
function demo(x, y, z){
    console.log(x, y, z);
}
demo.apply(null, arr);// 1 2 3

利用apply来达到目的
看起来怪怪的
而现在我们可以这样做

let arr = [1, 2, 3];
function demo(x, y, z){
    console.log(x, y, z);
}
demo(...arr);// 1 2 3    《--

##数组字面量
ES6之前我们想要拼接数组
可以使用concat()

var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];
var arr = arr1.concat(arr2);
console.log(arr);// [1, 2, 3, 4, 5, 6]

利用展开操作符就不需要调用这个方法了

var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];
var arr = [...arr1, ...arr2];
console.log(arr);// [1, 2, 3, 4, 5, 6]

##展开对象
展开数组是如此简单易用
那么对象呢?

let person = {
    name: 'payen',
    sex: 'male',
};
person = {...person, age: 19};
console.log(person);

把这段代码放在你的编辑器了
你会发现它根本不能运行
因为ES6根本没有这样的语法
不过它是ES7的提案之一
可以让我们以更加简洁的形式
将一个对象的可枚举属性复制到另一对象上
(ps:这一特性可以通过Babel及其插件实现)
(ps:React在JSX语法已经采用这种写法)
#箭头函数
箭头函数是一种更简单的函数声明方式
它永远是匿名函数
我们一般的函数写法

var sum = function(a, b){
    return a + b;
};

箭头函数

let sum = (a, b) => {
    return a + b;
};

当“箭头”后面是表达式的时候
还可以简化(省略“{ }”大括号 和 return关键字)

let sum = (a, b) => a + b;

略去function关键字
“=>”的前面是“( )”和内部的参数列表
“=>”的后面是代码块

这个胖胖的箭头被人为 单调乏味冗长 的function关键字的简写
(不过我觉得现在所有英文单词中function这个词我敲得最快(+﹏+)~)
不过它的作用可不仅仅是略微提高一点我们键盘的寿命
这个一会儿再说

##回调函数
先来看看它在回调函数中应用它

var arr = [1, 2, 3];
console.log(arr.map((value)=>value*2));// [2, 4, 6]

不知道大家能不能看懂
它就相当于下面的代码

var arr = [1, 2, 3];
console.log(arr.map(function(value){
    return value*2;
}));// [2, 4, 6]

##返回对象
还有一点要注意
就是如果我们的函数只是返回一个对象

var foo = function(){
    return {
        name: 'payen'
    }
}

使用箭头函数简化一步

let foo = () => {
    return {
        name: 'payen'
    }
}

再简化一步

let foo = () => {name: 'payen'}; //错误的写法

这时我的编辑器提示语法问题了
这是应为它认为“=>”后面是一个代码块
而不会理解为是要返回的对象
解决办法仍然是使用万能的“( )”
这样编辑器、浏览器都会认为它是表达式了

let foo = () => ({name: 'payen'}); //正确的写法

##this指向
嵌套函数就会产生this指向的问题
举个例子

var flag = 'global';
var obj = {
    flag: 'object',
    method: function(){
        console.log(this.flag);
        setTimeout(function(){
            console.log(this.flag);
        }, 200)
    }
};
obj.method();//object global

即便把var声明全改为let也会输出 object undefined
第一个console.log不用说
对象的嵌套函数会指向全局window对象
method方法丢失了同this之间的绑定
这被认为是JavaScript在设计上的重大缺陷
我们一般都会采用一些hack来解决


使用临时缓存变量
借助于词法作用域
利用一个标识符self(通常起名self、that、_this)
(ES3)

var flag = 'global';
var obj = {
    flag: 'object',
    method: function(){
        var self = this;
        setTimeout(function(){
            console.log(self.flag);
        }, 200)
    }
};
obj.method(); //object

或者利用bind()
(ES5)

//ES5
var flag = 'global';
var obj = {
    flag: 'object',
    method: function(){
        setTimeout(function(){
            console.log(this.flag);
        }.bind(this), 200)
    }
};
obj.method(); //object

现在使用箭头函数可以轻松解决问题
(ES6)

var flag = 'global';
var obj = {
    flag: 'object',
    method: function(){
        setTimeout(()=>console.log(this.flag), 200);
    }
};
obj.method(); //object

我们看到
箭头函数在涉及this绑定时的行为
与普通函数行为完全不同
它是用当前的此法作用域覆盖this本来的值
(“继承”了method()方法的this绑定)

最后还是要向大家强调一下箭头函数不够理想的一点
它是匿名而不是具名的


[==主页传送门==](http://blog.csdn.net/q1056843325)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/q1056843325/article/details/53860550

智能推荐

海康威视及大华技术SDK C头文件转Delphi Pas文件_大华录像机api下载pas代码-程序员宅基地

文章浏览阅读432次。https://blog.csdn.net/BlueStorm/article/details/106661600_大华录像机api下载pas代码

excel计算二元线性回归_快速掌握Logistic回归分析及应用-程序员宅基地

文章浏览阅读1.5k次。影响关系研究是所有研究中最为常见的。我们都知道当Y是定量数据时,线性回归可以用来分析影响关系。如果现在想对某件事情发生的概率进行预估,比如一件衣服的是否有人想购买?这里的Y是“是否愿意购买”,属于分类数据,所以不能使用回归分析。如果Y为定类数据,研究影响关系,正确做法是选择Logistic回归分析。01. 概念Logistic回归分析也用于研究影响关系,即X对于Y的影响情况。Y为定类数据,X可以是..._excel二元logistic回归

Tensorflow2 二次训练和断点续训_tensorlfow使得下次训练从断开的epoch地方开始继续训练-程序员宅基地

文章浏览阅读1.8k次,点赞3次,收藏12次。EnvironmentTensorflow2.0.0 python3.6问题描述每轮训练中以特定方式(固定频率、最高准确率或最低loss等)存储模型,停止训练后,基于已存储的模型进行二次训练。以特定方式保存模型callbacks = [ tf.keras.callbacks.ModelCheckpoint(filepath=save_args['./saved_models/model_epoch{epoch}.h5'], _tensorlfow使得下次训练从断开的epoch地方开始继续训练

tensorflow GPU安装及测试_测试tensorflowgpu csdn-程序员宅基地

文章浏览阅读1.8w次。# 一、TensorFLow-Gpu环境的搭建## 查看nvidia的型号以便安装相应的驱动lspci | grep -i nvidia#这一步非常的重要,一定要看清楚自己的驱动型号,以便能够找到正确的cuda和cudnn的型号 ## 禁用nouveau#在安装cuda的时候,由于涉及到NVIDIA驱动的安装,使得nouveau驱动与NVIDIA驱动冲突,为了能够继续安装,必须禁..._测试tensorflowgpu csdn

【Web API系列教程】2.1 — ASP.NET Web API中的路由机制_apicontroller 路由定义-程序员宅基地

文章浏览阅读5.5k次,点赞2次,收藏7次。这篇文章描述了ASP.NET Web API如何将HTTP请求发送(路由)到控制器。备注:如果你对ASP.NET MVC很熟悉,你会发现Web API路由和MVC路由非常相似。主要区别是Web API使用HTTP方法来选择动作(action),而不是URI路径。你也可以在Web API中使用MVC风格的路由。这篇文章不需要ASP.NET MVC的任何知识。路由表在ASP.NET Web API中,控_apicontroller 路由定义

Qslider样式_qslider 样式-程序员宅基地

文章浏览阅读1.3k次。QSlider::groove:horizontal {border: 1px solid #bbb;background: white;height: 10px;border-radius: 4px;}QSlider::sub-page:horizontal {background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop:..._qslider 样式

随便推点

面试题更新之-使用 base64 编码的优缺点_中文base64会有什么问题-程序员宅基地

文章浏览阅读748次。它将三个字节的二进制数据分割成四组,每组6个比特,然后将这些6个比特转换为可打印的ASCII字符。由于每个Base64编码单元包含6个比特,所以它的取值范围为0-63,通过指定一个映射表将这些值转换为相应的ASCII字符。分组和填充:由于Base64编码采用四个字符来表示每个编码单元,所以在编码过程中需要将24比特的编码单位划分为4个6比特的组。如果二进制数据的长度不是3的倍数,就需要进行填充。编码单位:Base64编码将三个字节的二进制数据作为一个编码单位处理,每个字节占8个比特,总共24个比特。_中文base64会有什么问题

java8 接口的默认方法和静态方法_java 8在接口中加上静态方法表示相关的工厂或助手方法-程序员宅基地

文章浏览阅读1.5k次,点赞2次,收藏2次。java8 接口的默认方法和静态方法首先我们要总体说一下,为什么要有这两个方法存在:(1)原先的jdk7之类的,它们接口中的方法都是抽象方法,没有具体的实现,就相当于定义好了这个接口有哪些功能,却没有具体定义功能是怎么实现的,通常由接口的实现类来做具体功能实现。那么,如果面向接口编程,大家已经根据自己需要通过继承接口的方式来实现了自己的功能,突然有一天,产品提需求了,你需要给所有接口的实现_java 8在接口中加上静态方法表示相关的工厂或助手方法

文本-----wangEditor的使用,设置和获取内容,展示HTML无样式怎么办????console同步展示怎样写,Vue的配置在Vue3配置文件中的配置,是editor中的v-model绑定的值_wangeditor sethtml-程序员宅基地

文章浏览阅读405次,点赞8次,收藏5次。【代码】文本-----wangEditor的使用,设置和获取内容,展示HTML无样式怎么办????console同步展示怎样写,在onChange事件中配置,编辑器配置,Vue的配置在Vue3配置文件中的配置。_wangeditor sethtml

京东科技全链路故障诊断智能运维实践-程序员宅基地

文章浏览阅读161次。本文根据张静老师在〖2023 中国数据智能管理峰会-上海站〗现场演讲内容整理而成。讲师介绍张静,京东科技智能运维算法高级经理。硕士毕业于东北大学,持续深耕智能运维领域多年,带领团队致力于京东智能运维算法迭代,把智能算法能力落地京东线上横向业务场景,算法在监控、数据库、网络、资源调度等多个纵向场景取得突破,提升了产品和运维的技术竞争力。善于将实践中沉淀的技术与日常算法工作中积累的技术与创新总结成专利..._京东 全链路跟踪

kernel 2.6.34 配置文件 (thinkpad sl400)_kernel_version or cpu_arch: ' 5.15 x86_64 ' not me-程序员宅基地

文章浏览阅读3.7k次。## Automatically generated make config: don't edit# Linux kernel version: 2.6.34-gentoo# Wed Jun 2 21:12:35 2010#CONFIG_64BIT=y# CONFIG_X86_32 is not setCONFIG_X86_64=yCONFIG_X86=y

LaTex的Beamer中的数学公式与论文中的数学公式不一样的解决办法_latex beamer 公式-程序员宅基地

文章浏览阅读2.2k次。同样的 latex 数学公式,在论文 (Article)模板中显示格式与在幻灯片( Beamer) 中的显示风格是不一样的,Beamer中的数学公式是如此丑陋不堪。\begin{equation}\mathcal{L}_{D}=\mathbb{E}_{x\sim P_{data}}[-\log D(x)]+\mathbb{E}_{z\sim P_{z}}[-\log (1-D(G(z)))]\label{equ-1}\end{equation}论文中的公式为:Beamer中的公式为:风格_latex beamer 公式