ES6指北【4】——ES6的函数参数处理,超乎你想象

2018-08-14 admin

一、函数的默认参数值

1. ES6之前,我们如何实现函数默认参数

1.1 方式一:使用逻辑运算符【||】

function test(x) {
  x = x || '默认值' // 使用||设置默认值
  console.log(x) 
}

test() // '默认值'

但这样做有个非常明显的缺陷 如果x的值为null/+0或-0/NaN/''/false中的一个,x都会被设置为默认值,但我们的本意是在不传值的时候才设置为默认值

因此有了第二种处理方式

1.2 方式二:对参数是否为undefined进行判断

ES5其实本来就有函数默认参数,只不过这个默认参数只能是undefined,无法设置

function test(x) {
  console.log(x)
}

test() // undefined

所以我们只要对传入的值是否为undefined进行判断就可以实现自由设置默认参数了

function test(x) {
  if(!(Object.prototype.toString.call(x) === "[object Undefined]")) {
    console.log('默认值')
  } else {
    console.log(x) 
  }

}

test() // '默认值'

2. ES6实现函数默认参数

2.1 基本用法

其实非常简单,直接在参数后面加个 = 号就行啦,看栗子吧

function test(x = '默认值') {
  console.log(x) 
}

test() // '默认值'

如果要给多个参数赋值,就像下面这样写

function test(x = '默认值1',y = '默认值2') {
  console.log(x,y) 
}

test() // 默认值1 默认值2

2.2 参数默认值的惰性求值

参数默认值是不记录值的,每次都会重新计算参数默认表达式的值

// 阮一峰老师 ES6深入浅出 的例子
let x = 99;
function foo(p = x + 1) {
  console.log(p);
}

foo() // 100

x = 100;
foo() // 101 而不是 100
// mdn的例子
function append(value, array = []) {
  array.push(value);
  return array;
}

append(1); //[1]
append(2); //[2] 而不是 [1, 2]

有同学一定会有疑问,这不是废话吗?其实不然,比如Python的参数默认值不一定是惰性求值,比如下面这个例子

>>> def f1(data=[]):
...     data.append(1)
...     return data
...
>>> f1()
[1]
>>> f1()
[1, 1]
>>> f1()
[1, 1, 1]

二、剩余参数

函数剩余参数的英文为 —— Functions Rest Parameters,一般我们剩余参数为rest参数

1. 基本概念

注:概念摘自阮一峰老师的《ECMAScript 6 入门》 ES6 引入 rest 参数(形式为...变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

从上面的概念中,我们至少可以知道如下三个信息

  1. 语法——...+变量。这个变量的数据类型是数组,用来存放多余的参数
  2. 作用——用于获取函数的多余参数
  3. 语法糖——rest参数一定是arguments对象的语法糖

1.1 基本用法

首先我们要搞清楚什么是多余参数

function sum(x, y) {
  return x + y
}

sum(1, 2, '多余1', '多余2', '多余3') // 3

从上面的例子我们可以看到,sum函数接受两个参数的传递,但是用户传递了五个参数,后面的三个参数即使传递也是无法被sum函数使用,显得有些多余

这里的多余并不是无用的意思,而是相对于被使用到了的参数显得多余而已

那么,如果我们也想对这些多余参数进行处理的话就需要使用rest参数

// 用rest参数改写之后
function sum(x, y, ...paraArr) {
  console.log(paraArr)
  return x + y
}

sum(1, 2, '多余1', '多余2', '多余3') 
// ["多余1", "多余2", "多余3"] 3 

1.2 什么时候我们会用到rest参数?

既然rest参数是arguments的语法糖,那么我们只要搞清楚以往arguments的应用场景是什么,那么自然就懂得如何使用rest参数了。

下面看一个使用arguments的例子

// 创建一个sum函数,实现如下功能
// sum() // 0
// sum(1) // 1
// sum(2,10,2) // 14
// sum(0,0,200,1) // 201
// sum(1,10,3,2,100) // 116

function sum() {
  let total = 0
  for (let i = 0; i < arguments.length; i++) {
      total += arguments[i]
  }
  return total
}

从上面的例子我们可以发现其最大的特点是参数个数不确定,所以如果遇到函数参数个数不确定的情况,就要优先考虑使用rest参数,而且由于rest参数真数组,你用起来会比arguments舒服太多 下面是用rest参数进行改写

// 创建一个sum函数,实现如下功能
// sum() // 0
// sum(1) // 1
// sum(2,10,2) // 14
// sum(0,0,200,1) // 201
// sum(1,10,3,2,100) // 116

function sum(...paraArr) {
  let total = 0
  paraArr.forEach(e => total += e)
  return total
}

2. 拓展:把arguments转换为真数组的三种方式

arguments因为能获取到所有参数所以还是有它的不可替代性的,但是其伪数组的特性实在有点恶心,下面教大家三种方法转换,第一种是ES5的方法,剩下两种是ES6的方法

function sum() {
  let arr1 = Array.prototype.slice.call(arguments)
  let arr2 = Array.from(arguments)
  let arr3 = [...arguments] // 这个是展开语法【spread syntax】 我会在ES6指北的下一章讲解,敬请关注~~
}

原文链接:https://segmentfault.com/a/1190000016002003

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-37948.html

文章标题:ES6指北【4】——ES6的函数参数处理,超乎你想象

相关文章
Android中Okhttp3实现上传多张图片同时传递参数
之前上传图片都是直接将图片转化为io流传给服务器,没有用框架传图片。 最近做项目,打算换个方法上传图片。 Android发展到现在,Okhttp显得越来越重要,所以,这次我选择用Okhttp上传图片。 Okhttp目前已经更新到Okhttp...
2017-03-17
Node.js 2014这一年发生了什么
Node.js 的 2014 年充满了不幸和争议. 这一年 Noder 们经历了太多的伤心事, 经历了漫长的等待, 经历了沉重的分裂之痛. 也许 Noder 们不想回忆14年 Node.js land 发生的事情, 但正因为痛才更有铭记的价...
2015-11-12
从2014年的发展来展望JS的未来将会如何
&lt;font face=&quot;寰�杞�闆呴粦, Arial, sans-serif &quot;&gt;2014骞达紝杞�浠惰�屼笟鍙戝睍杩呴€燂紝鍚勭�嶈��瑷€灞傚嚭涓嶇┓锛屼互婊¤冻鐢ㄦ埛涓嶆柇鍙樺寲鐨勯渶姹傘€傝繖浜涜��...
2015-11-12
12个你未必知道的CSS小知识
虽然CSS并不是一种很复杂的技术,但就算你是一个使用CSS多年的高手,仍然会有很多CSS用法/属性/属性值你从来没使用过,甚至从来没听说过。 1.CSS的color属性并非只能用于文本显示 对于CSS的color属性,相信所有Web开发人员...
2015-11-12
ajax为什么令人惊异?ajax的优缺点
使用Ajax的最大优点,就是能在不更新整个页面的前提下维护数据。这使得Web应用程序更为迅捷地回应用户动作,并避免了在网络上发送那些没有改变的信息。 Ajax不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。就像DHT...
2015-11-12
HTML5的5个不错的开发工具推荐
HTML5规范终于在今年正式定稿,对于从事多年HTML5开发的人员来说绝对是一个重大新闻。数字天堂董事长,DCloud CEO王安也发表了文章,从开发者和用户两个角度分析了HTML对两个人群的优势。其实,关于HTML5的开发工具,我们以往的...
2015-11-12
JavaScript教程:JS中的原型
Keith Peters 几年前发表的一篇博文,关于学习没有“new”的世界,其中解释了使用原型继承代替构造函数。两者都是纯粹的原型编码。 标准方法(The Standard Way) 一直以来,我们学习的在 JavaScript 里创建对...
2015-11-12
AJAX的浏览器支持
AJAX 的要点是 XMLHttpRequest 对象。 不同的浏览器创建 XMLHttpRequest 对象的方法是有差异的。 IE 浏览器使用 ActiveXObject,而其他的浏览器使用名为 XMLHttpRequest 的 Jav...
2015-11-12
Riot.js:不足1KB的MVP客户端框架
Riot.js是一款MVP(模型-视图-呈现)开源客户端框架,其最大的特点就是体积非常小,不足1KB,虽然体积小,但它可以帮助用户构建大规模的Web应用程序。 Riot.js是由Moot公司开发,目前最新版本为v0.9.2,遵循MIT开源许...
2016-03-11
typeof、instanceof和contructor的区别
typeof:以字符串的形式返回变量的原始类型,typeof在两种情况下会返回&quot;undefined&quot;:一个变量没有被声明的时候,和一个变量的值是undefined的时候,注意,typeof null也会返回object,...
2015-11-12
回到顶部