一:关于函数的参数:
可以接受任意数量的参数而无视函数声明的参数数量是js函数的独特之处。
1:参数默认值
ES6之前做法:
function makeRequest(url,timeout,callback){
timeout=timeout||2000;
callback = callback||function(){}
}
但是这样timeout如果设置为0,还是会使用默认值。因此更安全的方法是使用typeof来检测类型。
function makeRequest(url,timeout,callback){
timeout=(typeof timeout !=='undefined')?timeout:2000;
}
ES6做法:
functiong makeRequest(url,timeout=2000,callback=functing(){}){}
//只有在传入undefined或者不传时才会使用默认值 如果参数是null不适用默认值
makeRequest("xxxx",undefined,null)//第一个"xxxx",第二个使用默认值2000,第三次使用null
2:arguments对象
function mixArgs(first,second = 'b'){
arguments.length = 1
first === arguments[0] true;
second ===arguments[1] false;//second='b', arguments[1]='undefined'
}
mixArgs(1);
arguments对象的值传入后就不在改变永远等于初始值。
3:默认参数表达式
function getValue(value){
return value+5;
}
//表达式中可以说使用之前的参数,但不能使用后面的参数
function add (first,second=getValue(first)){
}
4:不具名参数
arguments对象包含的是传入的全部参数,有时候操作起来还是比较麻烦。
ES6通过引入剩余参数,可以包括显示声明的其他参数。
function pick(obj,..keys){
}
1:剩余参数只能发到最后
2:剩余参数不能再对象的setter属性中使用,因为setter被限定为只是用单个参数,而剩余参数是不限定数量的。
二:块级函数:
"use strict"
if(true){
console.log(type doSomething);// "function"
function doSomething(){}
doSomething();
}
console.log(type doSomething);// "undefined" 如果是非严格模式这里也会是"function"
在严格模式下定义的块级函数会被提升到块级作用域的顶部。而在非严格模式下会被提升至全局作用域,因此在代码块外部依然可以使用。
"use strict"
if(true){
console.log(type doSomething);// "undefined"//函数表达式不能提升 因此这里暂时性死区
let doSomething = function(){}
doSomething();
}
console.log(type doSomething);// "undefined"
三:箭头函数:
1:没有this,super,arguments,也没有new.target绑定,这些值由离箭头函数最近的非箭头函数来决定.
2:不嫩被使用new调用,箭头函数没有构造方法,使用new调用会报错。
3:不能更改this
function createArrow(){ return ()=>argument[0]}
var arrowFunction = createArrow(5)
console.log(arrowFunction()) // 5
四:尾调用优化:
满足三个条件es6在严格模式下会优化(非严格模式不变)
1:为调用不能引用当前栈帧的变量(意味着该函数不能是闭包)
2:进行尾调用的函数在返回结果后不能做额外操作
3:尾调用的结果作为当前函数的返回值
"use strict"
//不优化 没有return
function doSomething(){
doSomethingElse()
}
//不优化 返回后还要执行加法
function doSomething(){
return 1+ doSomethingElse()
}
//不优化 调用未在尾部
function doSomething(){
let res = doSomethingElse();
return res;
}
//不优化 访问内部变量
function doSomething(){
let num = 1;
let func = ()=>num;
return func();
}
function factorial(n){
if(n<=1){
return 1;
} else{
//不优化 返回后还要执行乘法
return n*factorial(n-1);
}
}
//优化后
function factorial(n,p=1){
if(n<=1){
return 1*p;
}else{
let result = n*p;
return factorial(n-1,result);
}
}