箭头函数
这是 ES6 中引入的一个有趣的新特性。箭头函数,顾名思义就是一种使用箭头(=>)定义的新语法,与传统函数的差别如下:
- 没有this、super、arguments和new.target绑定,他们由外围最近一层非箭头函数决定。
- 不能通过New关键字调用。箭头函数没有 construct 方法,所以不能用作构造函数。
- 没有原型,所以不存在 prototype 属性。
- 不可以改变this绑定,函数内部的this值不可以被改变,在函数生命周期内始终保持一致。
- 不支持arguments对象,箭头函数没有arguments绑定,所以必须通过命名参数和不定参数两种形势访问函数的参数。
- 不支持重复命名参数,传统函数只有在严格模式下才不能有重复命名的参数。
箭头函数的语法:
//加法
var add = function(a,b){
return a+b;
}
var sum = (a,b)=>a+b;
//排序的比较器
var result = values.sort((a,b)=>a-b);
其中箭头函数的参数为 ( => )左边括号的内容,右边为返回值。
尾调用优化
尾调用优化是ES6引擎的优化。之前的循环调用中,每一个未用完的栈帧都会被保存在内存中,当调用栈变得过大时程序会出现问题,例如爆栈。
尾调用优化就是指函数作为另一个函数的最后一条语句被调用。
function doSomething(){
return doSomethingElse();//尾调用
}
尾调用优化没有明确的语法,而是符合条件会自动优化。
在ES6中如果满足以下条件,尾调用不再创建新的栈帧,而是清楚并重要当前栈帧。(因为在ES5之前需要)
- 尾调用不访问当前栈的变量(函数不能是一个闭包)
- 在函数内部,尾调用是最后一条语句。
- 尾调用的结果作为函数值返回。
好处:
尾调用可以帮助函数保持一个更小的调用栈,从而减少内存的使用,避免栈溢出错误,当程序满足条件时,引擎会自动对其优化。
function factorial(n,p=1){
if(n<=1){
return 1*p;
}else{
let result = n*p;
//优化后
return factorial(n-1,result);
}
}
无法优化的示例:
"use strict"
function doSomething(){
//调用不在尾部无法优化.
var Result = doSomethingElse();
return Result;
}
function doSomething2(){
var sum =1;
fun = () =>num;
//无法优化,闭包
return func();
}
尾调用优化和函数的懒执行有异曲同工之妙,典型的案例就是斐波拉契数列。把时间复杂度从 N^2 下降到 N