Es6 函数
函数参数
剩余运算符
不定参数用来表示不确定参数个数,形如,…变量名,由…加上一个具名参数标识符组成。具名参数只能放在参数组的最后,并且有且只有一个不定参数
function f(...values){
console.log(values.length);
}
f(1,2); //2
f(1,2,3,4); //4
arguments
arguments 获取没有形参的函数值,es6中箭头函数不能使用arguments方法
function chen(){
console.log(arguments);
console.log(arguments.length);
}
chen(1,2,3,4);
//Arguments(5) [1, 2, 3, 4 callee: ƒ, Symbol(Symbol.iterator): ƒ]
//4
//可以用for循环拿取到每一个值
箭头函数
箭头函数提供了一种更加简洁的函数书写方式。基本语法是:
参数 => 函数体
var f = v => v; //等价于 var f = function(a){ return a; } f(1); //1
当箭头函数没有参数或者有多个参数,要用 () 括起来
var f = (a,b) => a+b;
f(6,2);
//8
当箭头函数函数体有多行语句,用 {} 包裹起来,表示代码块,当只有一行语句,并且需要返回结果时,可以省略 {} , 结果会自动返回
var f = (a,b) => { let result = a+b; return result; }
f(6,2);
// 8
当箭头函数要返回对象的时候,为了区分于代码块,要用 () 将对象包裹起来
// 报错 var f = (id,name) => {id: id, name: name};
f(6,2);
// SyntaxError: Unexpected token :
// 不报错
var f = (id,name) => ({id: id, name: name});
f(6,2);
// {id: 6, name: 2}
注意点:没有 this、super、arguments 和 new.target 绑定
箭头函数this指向永远指向window
var func = () => {
// 箭头函数里面没有 this 对象,
// 此时的 this 是外层的 this 对象,即 Window
console.log(this)
}
func(55) // Window
var func = () => {
console.log(arguments)
}
func(55);
// ReferenceError: arguments is not defined
箭头函数体中的 this 对象,是定义函数时的对象,而不是使用函数时的对象
function fn(){
setTimeout(()=>{
// 定义时,this 绑定的是 fn 中的 this 对象
console.log(this.a);
},0)
}
var a = 20;
// fn 的 this 对象为 {a: 18} fn.call({a: 18});
// 18
不可以作为构造函数,也就是不能使用 new 命令,否则会报错
函数闭包
①函数嵌套函数
②函数内部可以引用函数外部的参数和变量
③参数和变量不会被垃圾回收机制回收
function chen(a){
console.log(a)
return function(a){
console.log(a)
}
}
chen(4)(6);
//4
//6
每闭包一层,调用时传参就多加一个()来传入
闭包的优缺
好处:
1.保护函数内的变量安全 ,实现封装,防止变量流入其他环境发生命名冲突
2.在内存中维持一个变量,可以做缓存(但使用多了同时也是一项缺点,消耗内存) 3.匿名自执行函数可以减少内存消耗
坏处:
1.其中一点上面已经有体现了,就是被引用的私有变量不能被销毁,增大了内存消耗,造成内存泄漏,解决方法是可以在使用完变量后手动为它赋值为null;
2.其次由于闭包涉及跨域访问,所以会导致性能损失,我们可以通过把跨作用域变量存储在局部变量中,然后直接访问局部变量,来减轻对执行速度的影响
函数递归
递归就是函数根据条件自己调用自己
//使用递归深拷贝
function deepClone(obj){
let objs = Array.isArray(obj)?[]:{};
if(obj&&typeof obj==="object"){
for(key in obj){
if(obj.hasOwnProperty(key)){
if(obj[key]&&typeof obj[key]==="object"){
objs[key] = deepClone(obj[key]);
}else{
objs[key]=obj[key];
}
}
}
}
return objs;
}
//递归出来的对象/数组是属于深拷贝,与原对象/原数组互不干扰
//使用JSON.stringify(obj)和JSON.parse(_obj)也是深拷贝