ES 6 : 函数的扩展
1. 函数参数的默认值
[ 基本用法 ]
在ES6之前,不能直接为函数的参数指定默认值,只能采用变通的方法。
上面的代码检查函数log的参数y有没有赋值,如果没有,则指定默认值为world。这种写法的缺点在于,如果参数y赋值了,但是对应的布尔值为false,则该赋值不起作用。就像以上代码的最后一行,参数y等于空字符,结果被改为默认值。
ES6允许为函数的参数设置默认值,即直接写在参数定义的后面。
[ 与解构赋值默认值结合使用 ]
参数默认值可以与解构赋值的默认值结合起来使用。
[ 参数默认值的位置 ]
通常情况下,定义了默认值的参数应该是函数的尾参数。如果非尾部的参数设置默认值,实际上这个参数是无法省略的。
有默认值的参数都不是尾参数。这时,无法只省略该参数而不省略其后的参数,除非显式输入undefined。如果传入undefined,将触发该参数等于默认值,null没有这个结果。
[ 函数的length属性 ]
指定了默认值之后,函数的length属性将返回没有指定默认值的参数个数。
length属性的含义是,该函数预期传入的参数个数。某个参数指定默认值之后,预期传入的参数个数就不包括这个参数了。
[ 作用域 ]
如果参数默认值是一个变量,则该变量所处的作用域与其他变量的作用域规则是一样的,即先是当前函数的作用域,然后才是全局作用域。
如果调用时函数作用域内部的变量x没有生成,结果就会不一样。
函数调用时y的默认值变量x尚未在函数内部生成,所以x指向全局变量。
[ 应用 ]
利用参数默认值,可以指定某一个参数不得省略,如果省略就抛出一个错误。
以上代码中的foo函数,如果调用的时候没有参数,就会调用默认值throwIfMissing函数,从而抛出一个错误。
2. rest参数
ES6引入了rest参数(形式为"...变量名"),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest参数搭配的变量是一个数组,该变量将多余的参数放入其中。
以上代码中的add函数是一个求和函数,利用rest参数可以向该函数传入任意数目的参数。下面是rest参数代替arguments变量的例子。
// arguments 变量的写法
// rest 变量的写法
注意:rest参数之后不能有其他参数,函数的length属性不包括rest参数。
3. 扩展运算符
[ 含义 ]
扩展运算符是三个点(...)。它好比rest参数的逆运算,将一个数组转为用逗号分隔的参数序列。
扩展运算符与正常的函数参数可以结合使用。
- function f(v,w,x,y,z){}
- var args = [0,1];
- f(-1,...args,2,...[3]);
[ 替代数组的apply方法 ]
由于扩展运算符可以展开数组,所以不再需要apply方法将数组转为函数的参数了。下面是扩展运算符取代apply方法的一个实际的例子,应用Math.max方法简化求数组最大元素的写法:
- // ES5的写法
- Math.max.apply(null,[14,3,77])
- // ES6的写法
- Math.max(...[14,3,77])
[ 扩展运算符的应用 ]
- 合并数组
扩展运算符提供了数组合并的新写法。
- 与解构赋值结合
扩展运算符可以与解构赋值结合起来用于生成数组。
如果将扩展运算符用于数组赋值,只能放在参数的最后一位,不然会报错。
- 函数的返回值
JavaScript的函数只能返回一个值,如果需要返回多个值,只能返回数组或对象。扩展运算符提供了解决这个问题的一种变通方法。
- var dateFields = readDateFields(database);
- var d = new Date(...dateFields);
上面的代码用于从数据库中取出一行数据,通过扩展运算符直接将其传入构造函数Date。
- 字符串
扩展运算符还可以将字符串转为真正的数组。
[ 类似数组的对象 ]
任何类似数组的对象都可以用扩展运算符转为真正的数组。
- var nodeList = document.querySelectorAll("div");
- var array = [...nodeList];
上面的代码中,querySelectorAll方法返回的是一个nodeList对象,扩展运算符可以将其转为真正的数组。
[ Map 和 Set 结构,Generator 函数 ]
扩展运算符内部调用的是数据结构的Iterator接口,因此只要具有Iterator接口的对象,都可以使用扩展运算符,比如Map结构。
[ name属性 ]
函数的name属性返回该函数的函数名。
如果将一个匿名函数赋值给一个变量,ES5的name属性会返回空字符串,而ES6的name属性会返回实际的函数名。
如果将一个具名函数赋值给一个变量,则ES5和ES6的name属性都返回这个具名函数原本的名字。
5. 箭头函数
[ 基本用法 ]
ES6允许使用"箭头"(=>)定义函数。
- var f = v => v;
- // 上面的箭头函数等同于
- var a = function(v){
- return v;
- };
如果箭头函数不需要参数或需要多个参数,就使用圆括号代表参数部分。
- var f = () => 5;
- // 等同于
- var f = function(){ return 5 };
- var sum = (num1,num2) => num1 + num2;
- // 等同于
- var sum = function(num1,num2){
- return num1+num2;
- };
如果箭头函数的代码块部分多于一条语句,就要使用大括号将其括起来,并使用return语句返回。
- var sum = (num1,num2) => { return num1 + num2 }
由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号。
- var getTempItem = id => ({ id: id, name: "Temp" });
箭头函数可以与变量解构结合使用。
- const full = ({ first, last }) => first + '' + last;
- // 等同于
- function full(person){
- return person.first + '' + person.name;
- }
箭头函数使得表达更加简洁。
- const isEven = n => n % 2 == 0;
箭头函数的一个用处是简化回调函数。
- // 正常函数的写法
- [1,2,3].map(function(x){
- return x*x;
- });
- // 箭头函数的写法
- [1,2,3].map(x => x*x);
箭头函数还能与rest参数结合。
[ 使用注意点 ]
箭头函数有几个使用注意点。
● 函数体内的this对象就是定义时所在的对象,而不是使用时所在的对象。
● 不可以当做构造函数。也就是说,不可以使用new命令,否则会抛出一个错误。
● 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用rest参数代替。
● 不可以使用yield命令,因此箭头函数不能用作Generator函数。
6.函数绑定
箭头函数没有自己的this,导致内部的this就是外层代码块的this。正因为它没有this,所以也就不能用作构造函数。当然也不能使用call()、apply()、bind()这些方法去改变this的指向。
函数绑定运算符是并排的双冒号(::),双冒号左边是一个对象,右边是一个函数。该运算符会自动将左边的对象作为上下文环境绑定到右边的函数上。
- foo::bar
- // 等同于
- bar.bind(foo)
- foo::bar(...arguments)
- // 等同于
- bar.bind(foo,arguments)
如果双冒号左边为空,右边是一个对象的方法,则等于将该方法绑定在该对象上。
- var method = obj::obj.foo
- // 等同于
- var method = ::obj.foo
由于双冒号运算符返回的还是原对象,因此可以采用链式写法。
- import {map,takeWhild,forEach} from "iterlib";
- getPlayers()
- ::map(x => x.character())
- ::takeWhile(x => x.strength > 100);
- ::forEach(x => console.log(x));
7.尾调用优化
[ 尾调用概念 ]
尾调用是函数式编程的一个重要概念,本身非常简单,一句话就能说清楚,就是指某个函数的最后一步是调用另一个函数。
- function f(x){
- return g(x)
- }
以下情况都不属于尾调用:
- // 情况一
- function f(x){
- let y = g(x);
- return y;
- }
- // 情况二
- function f(x){
- return g(x)+1;
- }
- // 情况三
- function f(x){
- g(X);
- }
上面的代码中,情况一是调用函数g之后还有赋值操作,所以不属于尾调用,即使语义完全一样;情况二也属于调用后还有操作,即使写在一行内;情况三等同于下面的代码。
- function f(x){
- f(x);
- return undefined;
- }
ES 6 : 函数的扩展的更多相关文章
- ES6 - Note3:数组、对象与函数的扩展
一.数组的扩展,ES6在数组扩展了一些API,以实现更多的功能 1.Array.from:可以将类数组和可遍历的数据结构转换成真正的数组,如下所示 var a = { '0':1,'1':1,leng ...
- ES6入门之函数的扩展
函数js原有的: 属性:arguments[].caller(调用该函数的引用,注意与callee分别开,callee指的是调用函数本身经常在递归中出现).length(形参个数).prototype ...
- 编译器对C++ 11变参模板(Variadic Template)的函数包扩展实现的差异
编译器对C++ 11变参模板(Variadic Template)的函数包扩展实现的差异 题目挺绕口的.C++ 11的好东西不算太多,但变参模板(Variadic Template)肯定是其中耀眼的一 ...
- sqlserver 只有函数和扩展存储过程才能从函数内部执行
一个SQLServer的自定义函数中调用一个自定义的存储过程,执行此函数后发出如下提示:“只有函数和扩展存储过程才能从函数内部执行". 原因:函数只能使用简单的sql语句,逻辑控制语句,复杂 ...
- ES6_入门(6)_函数的扩展
// 2017/7/22 /*ES6函数的扩展*/ //ES6 之前,不能直接为函数的参数指定默认值,只能采用变通的方法. function log(x, y) { y = y || 'World'; ...
- ES6的新特性(7)——函数的扩展
函数的扩展 函数参数的默认值 基本用法 ES6 之前,不能直接为函数的参数指定默认值,只能采用变通的方法. function log(x, y) { y = y || 'World'; console ...
- php 函数追踪扩展 phptrace
php 函数追踪扩展 phptrace 介绍 phptrace 是一个低开销的用于跟踪.分析 php 运行情况的工具. 它可以跟踪 php 在运行时的函数调用.请求信息.执行流程.并且提供有过滤器.统 ...
- ES6学习(二):函数的扩展
chapter07 函数的扩展 7.1 函数默认值 7.1.1 参数默认值简介 传统做法的弊端(||):如果传入的参数相等于(==)false的话,仍会被设为默认值,需要多加入一个if判断,比较麻烦. ...
- ES6学习笔记(6)----函数的扩展
参考书<ECMAScript 6入门>http://es6.ruanyifeng.com/ 函数的扩展 函数的默认值 : ES6可以为函数指定默认值 (1)指定默认值的两种方式 a.函数参 ...
随机推荐
- 区域、模板页与WebAPI初步
区域.模板页与WebAPI初步 一.区域—麻雀虽小,五脏俱全的迷你MVC项目 1.1 Area的兴起 为了方便大规模网站中的管理大量文件,在ASP.NET MVC 2.0版本中引入了一个新概念—区域( ...
- 在Android中自动实现横竖屏切换的问题
http://developer.android.com/training/basics/supporting-devices/screens.html参照Google推荐的做法 在你项目的res 文 ...
- Oracle wrap 和 unwrap( 加密与解密) 说明
一. Wrap 说明 官网的说明如下: A PL/SQL Source Text Wrapping http://download.oracle.com/docs/cd/E11882_01/appde ...
- 【分享】Python学习资源大合集
地址:http://www.hejizhan.com/html/xueke/520/x520_03.html Python安装软件合集(Windows)(78) Python教程——游戏编程(13) ...
- C#函数式程序设计之泛型(下)
C#函数式程序设计之泛型(下) 每当使用泛型类型时,可以通过where字句对泛型添加约束: + 这个例子直观地声明了一个约束:类型T必须与ListItem<string>相匹配.泛型类 ...
- iOS基础 - 瀑布流
一.瀑布流简介 瀑布流,又称瀑布流式布局.是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部.最早采用此布局的网站是Pint ...
- MVC 5 - 将数据从控制器传递给视图
MVC 5 - 将数据从控制器传递给视图 在我们讨论数据库和数据模型之前,让我们先讨论一下如何将数据从控制器传递给视图.控制器类将响应请求来的URL.控制器类是给您写代码来处理传入请求的地方,并从数据 ...
- 使用MMS(MongoDB Monitoring Service)监控MongoDB
使用MMS(MongoDB Monitoring Service)监控MongoDB 一.MongoDB简介: MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可 ...
- [Usaco2008 Feb]Meteor Shower流星雨[BFS]
Description 去年偶们湖南遭受N年不遇到冰冻灾害,现在芙蓉哥哥则听说另一个骇人听闻的消息: 一场流星雨即将袭击整个霸中,由于流星体积过大,它们无法在撞击到地面前燃烧殆尽, 届时将会对它撞到的 ...
- 字符串比较strcmp
问题: 原型:extern int strcmp(const char *s1,const char * s2); 所在头文件:string.h 功能:比较字符串s1和s2. 一般形式:strcmp( ...