ES6学习笔记(6)----函数的扩展
参考书《ECMAScript 6入门》
http://es6.ruanyifeng.com/
函数的扩展
函数的默认值 : ES6可以为函数指定默认值
(1)指定默认值的两种方式
a.函数参数的默认值
function test(a = 0,b = 5){
return a+b;
}
test();//5 调用方法时,参数a,b都是undefined,可以使用默认值,因此返回5
test(7);//7+5 = 12
test(,10);//报错 非尾参数设置了默认值,则调用函数时此参数无法忽略,忽略报错;显示传入undefined,则触发默认值
在参数中定义了默认值的变量,代码块中不能再用let或const重新定义变量(let与const不允许在同一个作用域内重复声明同一个变量)
function test3(a = 1){
let a = 7;
return a;
}
test3()//执行此方法时报错(定义此方法test3时不报错)Uncaught SyntaxError: Identifier 'a' has already been declared
function test4(b = 'sdf'){
const b = 'test4';
return b;
}
test4()//执行此方法时报错(定义此方法test4时不报错)Uncaught SyntaxError: Identifier 'b' has already been declared
function test5(c = 8){
var c = 1;
return c;
}
test5()//1 不报错 let与const不允许在同一个作用域内重复声明同一个变量,而var可以,所以使用var重复声明c不报错
使用参数的默认值时,不可以在声明同名参数
function test6(a = 1, a, b){
return a+b;
}//函数定义时就报错 Uncaught SyntaxError: Duplicate parameter name not allowed in this context
b.对象的解构赋值默认值
function test2({a = 1,b = 8}){
return a+b;
}
test2({});//9此时参数是一个空对象,空对象里的属性全是undefined, 所以函数可以使用参数的默认值
test2({a:12,b:13});//25
test2({a:15});//23
test2();//此处使用的是对象的解构赋值默认值,如果传入的参数不是对象,就无法让对象的解构赋值默认值生效,报错 Cannot destructure property `a` of 'undefined' or 'null'.
//要解决此问题,可以将其转化为进一步的参数默认值
function test2({a = 2,b = 3} = {}){ //此处表示函数test2的默认参数是一个空对象,此空对象的属性a的默认值是2,属性b的默认值是3
return a+b;
}
test2({});//5
test2();//5
(2)指定默认值后length属性将失真,已经制定默认值的参数以及位置在其后的参数都不参与length计数
function test7(a,b,c,d){
return a+b+c+d;
}
test7.length //4
function test8(a,b = 0,c,d){
return a+b+c+d;
}
test8.length //1 只计算了一个参数a,定义了默认值的参数b以及其后的c,d均不参与length计数
(3)参数默认值是不传值的,如果参数默认值是一个表达式赋值,那每次都需要重新计算
(4)一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域(context)。等到初始化结束,这个作用域就会消失。这种语法行为,在不设置参数默认值时,是不会出现的。
(5)参数默认值用途:可用于提示某参数可省略(默认值设置成undefined)或者必须(默认值设置成可以返回异常提示语句的函数)
2.rest参数:rest参数是一个数组,length属性不记录rest参数。
function test11(...restParams){
return restParams;
}
test11(1,3,4,5,'qwe'); // [1,3,4,5,'qwe']
test11.length; //0
3.函数的name属性返回实际的函数名
let f = function test12(){};
f.name; // 'test12'
Array.bind({}).name; // "bound Array"
4.箭头函数
(1)箭头函数的this始终是函数定义时的this,不是使用时的this
function Timer(){
this.s1 = 0;
this.s2 = 0;
setInterval(()=>this.s1++,1000);//箭头函数中的this,指向Timer定义时的this,即this.s1 = 0;
setInterval(function(){
this.s2++;//常规写法函数中的this,通常指向使用时的window/document全局变量,因此this.s2是NaN,而timer.s2始终是定义时的值。
},1000);
}
var timer = new Timer();
setTimeout(()=>console.log(timer.s1),3100);//3
setTimeout(()=>console.log(timer.s2),3100);//0
(2)箭头函数可以简化函数写法
function insert(value){
return {into : function(arr){
return {afterValue : function(val){
arr.splice(arr.index(val)+1,0,value);
return arr;}
}}}
}
let insert = (value) => {into : (arr) => ({afterValue : (val) => {arr.splice(arr.indexOf(val)+1,0,value);return arr;}})}
(3)如果箭头函数右边返回的是代码块,用{}括起来;如果箭头函数右边的是对象,则必须使用({})括起来。
(a,b) => {return a+b}
let test13 = (a,b) => ({name : a,value : b})
test13("test",8); //{name : "test",value : 8}
(4)箭头函数不能做构造函数,即不能使用new命令
let test15 = (a,b) => a*b;
new test15(); //报错 Uncaught TypeError: test15 is not a constructor
5.双冒号运算符:左边是一个对象,右边是一个函数
object1 :: f1 //等同于f1.bind(object1)
object2 :: f2(...restArr) //等同于 f2.apply(object2,restArr);
::f3 //等同于f3.bind(f3)
::f3(...restArr1) //等同于f3.apply(f3,restArr1);
如果双冒号运算符的结果是一个对象,则可以链式使用
6.尾调用和尾调用优化
尾调用:函数的最后一步调用了另外一个函数
function test17(){
return test18();//必须是最后一步调用此函数,而且是作为返回值返回
}
尾调用优化:函数A最后一步调用了另外一个函数B,且函数B执行过程中不需要使用到任何有关函数A里变量的操作,那么在尾调用执行后,有关函数A的调用帧都可以删除,只保留函数B的调用帧,这即是尾调用优化
function A(a){
a = a + 1;
function B(b){
console.log(b);
}
return B('this is a test')
}
7.递归和尾递归
递归:函数调用自身
尾递归:函数尾调用自身
常见递归:遍历dom树
function traversal(node){
//对node的处理
if(node && node.nodeType === 1){
console.log(node.tagName);
}
var i = 0, childNodes = node.childNodes,item;
for(; i < childNodes.length ; i++){
item = childNodes[i];
if(item.nodeType === 1){
//递归先序遍历子节点
traversal(item);//属于尾递归
}
}
}
尾递归优化
普通尾递归
function sum(x){
if(x === 1) {return 1};
return x+sum(x - 1);//返回当前层次计算的x的值与下一子自身调用返回的值,因此当前的调用帧不能删除
}
优化后的尾递归
function sum(x,y){
if(x === 1) {return y};
return sum(x - 1,x+y);//执行后当前调用帧可以删除,进入下一次自调用的新参数的调用帧
}
5,1-->4,5+1
4,6-->3,5+1+4
3,11-->2,5+1+4+3
2,14-->1,5+1+4+3+2
1,15--->15
8.尾逗号规则:ES6允许函数定义时尾参数带逗号
function test16(p1,p2,p3,){}
ES6学习笔记(6)----函数的扩展的更多相关文章
- es6学习笔记9--函数的扩展
函数参数的默认值 基本用法 在ES6之前,不能直接为函数的参数指定默认值,为了避免这个问题,通常需要先判断一下参数y是否被赋值,如果没有,再等于默认值. ES6允许为函数的参数设置默认值,即直接写在参 ...
- ES6 学习笔记之四 对象的扩展
ES6 为对象字面量添加了几个实用的功能,虽然这几个新功能基本上都是语法糖,但确实方便. 一.属性的简洁表示法 当定义一个对象时,允许直接写入一个变量,作为对象的属性,变量名就是属性名. 例1: , ...
- es6学习笔记-async函数
1 前情摘要 前段时间时间进行项目开发,需求安排不是很合理,导致一直高强度的加班工作,这一个月不是常说的996,简直是936,还好熬过来了.在此期间不是刚学会了es6的promise,在项目有用到pr ...
- ES6学习笔记(一)——扩展运算符和解构赋值
前言 随着前端工程化的快速推进,在项目中使用ES6甚至更高的ES7等最近特性早已不是什么新鲜事.之前还觉得既然浏览器支持有限,那了解一下能看懂就好,然而仅仅了解还是不够的,现在放眼望去,那些成熟框架的 ...
- ES6学习笔记(三)——数值的扩展
看到这条条目录有没有感觉很枯燥,觉得自己的工作中还用不到它所以实在没有耐心看下去,我也是最近得闲,逼自己静下心来去学习去总结,只有在别人浮躁的时候你能静下心来去学去看去总结,你才能进步.毕竟作为前端不 ...
- ES6学习笔记二:各种扩展
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/7242967.html 一:字符串扩展 1:字符串遍历器 for (let char of str) { // ...
- ES6学习笔记(8)----对象的扩展
参考书<ECMAScript 6入门>http://es6.ruanyifeng.com/ 对象的扩展 1.属性名的简洁表示法 : ES6允许在代码中直接写变量,变量名是属性名,变量值是属 ...
- ES6学习笔记(5)----数值的扩展
参考书<ECMAScript 6入门>http://es6.ruanyifeng.com/ 数值的扩展 1.Number对象的扩展(1)javascript的全局函数isNaN,isFin ...
- ES6学习笔记之数组的扩展
✏️1. 扩展运算符 扩展运算符(spread)是三个点(...),将一个数组转为用逗号分隔的参数序列. 普通用法 console.log(...[1,2,3]);//1 2 3 数组拷贝(普通类型深 ...
随机推荐
- ie8的圆角问题
pie.js的引用 1.在你的网页加载 PIE.js 脚本. 注意,用IE专用的注释,防止非IE浏览器下载. <!--[if lt IE 10]> <script type=&quo ...
- YTU 1439: 2.4.5 Fractions to Decimals 分数化小数
1439: 2.4.5 Fractions to Decimals 分数化小数 时间限制: 1 Sec 内存限制: 64 MB 提交: 194 解决: 13 题目描述 写一个程序,输入一个形如N/ ...
- 一步一步学Silverlight 2系列(6):键盘事件处理
一步一步学Silverlight 2系列(6):键盘事件处理 概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言V ...
- 第一次通过AVD Manager创建了一个虚拟设备,但是在Android Studio运行程序时却无设备可选
第一次通过AVD Manager创建了一个虚拟设备,但是在Android Studio运行程序时却无设备可选 原因是adb.exe未运行起来 至于adb.exe未正常运行起来的原因多半是5037端口被 ...
- java中io类型及成熟io框架
就io本身而言,概念上有5中模型:blocking I/O, nonblocking I/O, I/O multiplexing(select and poll), singal driven I/O ...
- Android隐藏Activity和图标
今天发现4.0以后如果不写Activity只写BroadcastReceiver的话,这个广播接收器是不能运行的.经过查询,好像是HoneyComb之后添加了安全机制,规定必须运行一次Activity ...
- BZOJ_2017_[Usaco2009 Nov]硬币游戏_博弈论+DP
BZOJ_2017_[Usaco2009 Nov]硬币游戏_博弈论+DP Description 农夫约翰的奶牛喜欢玩硬币游戏,因此他发明了一种称为“Xoinc”的两人硬币游戏. 初始时,一个有N(5 ...
- BZOJ_4423_[AMPPZ2013]Bytehattan_对偶图+并查集
BZOJ_4423_[AMPPZ2013]Bytehattan_对偶图+并查集 Description 比特哈顿镇有n*n个格点,形成了一个网格图.一开始整张图是完整的. 有k次操作,每次会删掉图中的 ...
- liunx命令之【查看某个端口号的使用情况】
第一:查看端口占用情况的命令:lsof -i:<端口号>
- bzoj1996
区间dp 其实我们发现对于一段区间我们是这样构造的,每次我们会向两端放数,这样就有四种情况,且必须满足题意,初值是dp[i][i][0]=1,因为第一个人只有一种放法,不分左右.其实看见dp[i][i ...