ES6--函数的扩展

1.函数的默认值

从ES6开始,允许为函数参数设置默认值,即直接写在参数定义的后面。这样做使代码变得简洁自然,另外还有两个好处:

  • 可以方便明确的知道哪些参数有默认值是可以省略的
  • 有利于将来的代码优化,即使去掉这个参数也不会导致以前的代码无法运行

另外,参数变量是默认声明的,因此不能再使用let和const命令再次声明。定义了默认值的参数应该是函数的尾参数,这样就可以很容易的看出到底省略了哪些参数。如果尾部参数没有设置默认值那么是无法省略的。另外也无法直接省略处在中间的有默认值的参数,除非显示传入undefined

与解构赋值结合使用

function m1({x:0,y:0} = {}){
    return [x, y];
}

function m2({x,y} = {x:0,y:0}){
    return[x, y];
}

m1()//[0,0]
m2();//[0,0]

m1({x:3, y:8});//[3,8]
m2({x:3,y:8});//[3,8]

m1({x:3});//[3,0]
m2({x:3});//[3, undefined]

  

length属性

指定默认值以后函数的length属性返回的是没有指定默认值参数的个数,因为length属性的含义就是函数预期传入参数的个数,当某个参数指定了默认值以后预期的传入参数就不再包括已经指定默认值的参数。

2.rest参数与扩展运算符

ES6引入rest参数(形式为’…变量名’),用于获取函数的多余参数,该功能类似于Java中的不确定数量的参数,rest参数将不定个数的参数转换为名称为指定变量名的数组,然后我们可以通过众多的数组函数对其进行操作 
注意一点,rest函数必须是函数的最后一个参数否则会报错

与rest参数相反,扩展运算符  将一个数组转为用逗号分隔的参数序列。扩展运算符提供了众多的用途 
替代数组的apply方法

//ES5
Math.max.apply(null,[14,2,4]);
//ES6
Math.max(...[14,2,4]);

合并数组

var arr1 = [‘a‘, ‘b‘];
var arr2 = [‘c‘, ‘d‘];
var arr3 = [‘e‘];
//ES5
arr1.contact(arr2,arr3);
//ES6
[...arr1, ...arr2, ...arr3];//[‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘]

与解构赋值结合 
两者可以结合使用生成数组

const [first, ...rest] = [1, 2, 3, 4, 5];
first //1
rest //[2,3,4,5]

将字符串转为数组

[..."hello"]// [‘h‘, ‘e‘, ‘l‘, ‘l‘, ‘0‘]

转换类似数组的对象、Set、Map以及Generator函数、

//转换对象
var nodelist = document.querySelectorAll(‘div‘);
var array = [...nodelist]

//转换Map。Map和Set都是具有Iterator的对象, 只要是具有Iterator接口的对象都可以使用扩展运算符
let map = new Map([
    [1, ‘one‘],
    [2, ‘two‘],
    [3, ‘three‘],
    ]);
let arr = [...map.keys()];//[1, 2, 3]

//转换Generator函数,Generator函数运行后返回一个遍历器对象,因此也可以使用扩展运算符
var go = function*(){
    yield 1;
    yield 2;
    yield 3;
};

3.name属性

函数的name属性返回函数名,如果是匿名函数,ES5返回空字符串,而ES6返回实际的函数名。Function构造函数返回的函数示例name属性值为’anonymous’,bind返回的函数name属性值会加上’bound’前缀

var func1 = function(){};
func1.name;//ES5:""   ES6:func1

//如果将一个具名函数返回给一个变量,ES5/ES6都会返回这个具名函数原本的名字而不是变量名
const bar = function baz(){};
bar.name();//baz

4.箭头函数

ES6允许使用* 箭头 => *定义函数,箭头左边为参数,右边为方法体。如果不需要参数则用圆括号代表参数部分,如果方法体多于一行则用大括号括起来并用return表示返回。

var f = v => v;
//等价于
var f = function(v){ return v};

var f = ()=>5;
//等价于
var f = function(){
    return 5;
}

箭头函数的几点注意: 
* 函数体内的this总是该函数定义时所在的对象。因为箭头函数根本没有自己的this,因此其内部的this就是外层代码块的this 
* 不可以当做构造函数,即不可以使用new命令 
* 不可以使用arguments对象,该对象在函数体内不存在, 可以用rest代替 
* 不可以使用yield命令,因此箭头函数无法用作Generator函数

5.函数绑定、尾逗号以及尾调用优化

ES7提出了函数绑定用来取代call、apply、bind调用,运算符是双冒号* :: *, 其坐标是一个对象,右边是一个函数,它将自动将左边的对象作为上下文环境(即this对象)绑定到右边的函数中。其返回的还是原对象因此可以使用链式调用

尾调用优化

尾调用是函数式编程的一个重要概念, 指某个函数的最后一步是调用另一个函数。尾调用可以不出现在尾部,只要是函数操作的最后一步即可。

在函数的调用过程中,会形成调用栈,尾调用与其他的调用不同在于因为尾调用是函数的最后一步操作,因此不需要外层函数的调用栈,这样就只保留了内层的调用栈。因此如果所有的函数都是尾调用那么完全可以做到每次执行调用时只有一帧,将大大的节省内存,这就是所谓的尾调用优化

尾调用可以对递归进行优化。函数调用自身成为递归,如果尾调用自身就成为尾递归。因为可能需要保存大量的调用栈因此非常消耗内存。尾递归很好的解决了这一问题。 
尾递归的实现往往需要改写递归函数,确保其最后只调用自身。方法就是:把所有用到的内部变量变为函数的参数。但这么做会导致函数的可读性降低,这里有两个方法解决: 
一是在尾递归函数之外再提供一个正常形式的函数来调用尾递归函数,另一个就是柯里化,是函数式编程的一个概念,是将多参数的函数转换为单参数的形式。

尾逗号

从ES6开始允许函数的最后一个参数有尾逗号

function func(
  foo,
  bar,){
}
时间: 2024-12-17 04:06:14

ES6--函数的扩展的相关文章

ES6函数的扩展

1.运用ES6的默认参数 2.|| 和  |     && 和  & 什么区别? https://zhidao.baidu.com/question/2118237346586349547.html a||b  a为true的话后面就不执行了a|b   a为true的话后面继续判断ba&&b   a如果是false 后面的b就不去判断a&b   a如果是false 后面继续判断b 3.rest参数(形式为"...变量名")可以称为不定参数

ES6函数扩展

前面的话 函数是所有编程语言的重要组成部分,在ES6出现前,JS的函数语法一直没有太大的变化,从而遗留了很多问题和的做法,导致实现一些基本的功能经常要编写很多代码.ES6大力度地更新了函数特性,在ES5的基础上进行了许多改进,使用JS编程可以更少出错,同时也更加灵活.本文将详细介绍ES6函数扩展 形参默认值 Javascript函数有一个特别的地方,无论在函数定义中声明了多少形参,都可以传入任意数量的参数,也可以在定义函数时添加针对参数数量的处理逻辑,当已定义的形参无对应的传入参数时为其指定一个

ES6 - Note3:数组、对象与函数的扩展

一.数组的扩展,ES6在数组扩展了一些API,以实现更多的功能 1.Array.from:可以将类数组和可遍历的数据结构转换成真正的数组,如下所示 var a = { '0':1,'1':1,length:2 }; var arr = Array.from(a); console.log(arr) Array [ 1, 1 ] ---------------ES5的实现----------- var arr = [].slice.call(a); console.log(arr) Array [

ES6学习(二):函数的扩展

chapter07 函数的扩展 7.1 函数默认值 7.1.1 参数默认值简介 传统做法的弊端(||):如果传入的参数相等于(==)false的话,仍会被设为默认值,需要多加入一个if判断,比较麻烦. 参数变量是默认声明的,不可在函数体内部重复声明. 参数的默认值会在每次调用的时候重新计算 7.1.2 和解构赋值默认值结合使用 用两个例子来说明 Example1 function foo({x, y=5}) { console.log(x, y); } foo({}) // undefined,

数组的复制及ES6数组的扩展

一.数组的复制 // alert([1,2,3]==[1,2,3]); let cc = [0,1,2]; let dd = cc; alert(dd==cc);//此时改变dd会影响cc ES5 只能用变通方法来复制数组. const a1 = [1, 2]; const a2 = a1.concat(); a2[0] = 2; a1 // [1, 2] //使用ES6语法会防止这种现象出现 const a1 = [1, 2]; // 写法一 const a2 = [...a1]; // 写法

关于C gets,fgets,gets_s函数一些扩展

自己写的,第一位观众席肯定是留给自己的. 前言废话: 工作之后总是忘不了当初学C时的感觉,那种调试,改错,成功后喜悦.虽简单到麻木,但是那是真的有点喜欢. 估计同老剧本很像,没钱时,放弃了自己喜欢的,有钱时,又想回去找Ta.估计也想是我那朋友"网视悠悠"说的"人生的矛盾" 之一吧.随着自己学习的深入,从最初的M$的.Net开发,逐渐走向C开发.也解决了最初的语言问题.因为我本身就不是 一个纯粹的程序员.我以前学的是数学.一直瞧不起搞编程的.这么简单的活.就是在玩堆积

Javascript使用函数apply扩展环境对象

Javascript使用函数apply扩展环境对象 通过实例对象作为参数传入调用构造函数对象的apply方法,以使实例对象作为环境对象在作为一个普通函数的构造函数中执行,构造函数的属性会覆盖到实例对象上,从而实现实例对象的属性扩展. 1.函数对象的apply和call传入参数     var tag = "global";      function say(){          for(var args = "", i = 0; i < arguments

编译器对C++ 11变参模板(Variadic Template)的函数包扩展实现的差异

编译器对C++ 11变参模板(Variadic Template)的函数包扩展实现的差异 题目挺绕口的.C++ 11的好东西不算太多,但变参模板(Variadic Template)肯定是其中耀眼的一颗明星,在C++设计新思维中,你可以看到很多模版的代码为了支持不确定的参数个数,而要重载1个参数到N个模板参数的N个函数.虽然种代码一般也是用会用宏和脚步辅助生成.但我想也没有人愿意看到几千行这种单调的函数.通过这个东东,模板的威力可以爆发. 目前的最新的编译器基本都已经支持Variadic Tem

第七课:数值以及函数的扩展和修复

1.数值扩展和修复 toFixed(num) 方法可把 Number 四舍五入为指定小数位数的数字.num必需,规定小数的位数,是 0 ~ 20 之间的值,包括 0 和 20,有些实现可以支持更大的数值范围.如果省略了该参数,将用 0 代替.返回 NumberObject 的字符串表示,不采用指数计数法,小数点后有固定的 num 位数字.如果必要,该数字会被舍入,也可以用 0 补足,以便它达到指定的长度.如果 num 大于 le+21,则该方法只调用 NumberObject.toString(

sqlserver 只有函数和扩展存储过程才能从函数内部执行

一个SQLServer的自定义函数中调用一个自定义的存储过程,执行此函数后发出如下提示:“只有函数和扩展存储过程才能从函数内部执行". 原因:函数只能使用简单的sql语句,逻辑控制语句,复杂一点的存储过程是不能调用的,在函数里也不能使用execute  sp_executesql  或者execute .解决方法把函数改为存储过程,然后在另一个存储过程中象调用函数一样使用此存储过程就可以了. 下面是一个存储过程调用另一个存储过程的实例,有参数传递的. --存储过程sp_B    create