[TOC] >[success] # 参数篇章 [想更快了解es6函数参数使用请直接参考这里](https://www.kancloud.cn/cyyspring/more/1006387) >[info] ## es6让函数可以像pyhton一样使用默认参数 >[danger] ##### es5 模拟默认参数缺点 ~~~ function getParam(param){ let a = param || 'default'; return a; } // 如果参数传入0,也会走默认参数'default'不是我们想要的结果 setParam1 = getParam(0); ~~~ * 解决'||' 这种形式漏洞 ~~~ //解决漏洞需要使用typeof来做 function show(a,b){ var a=typeof a === 'undefined'?20:a; var b=typeof b === 'undefined'?30:b; console.log(a,b) } show(0,0) //0 0 ~~~ >[danger] ##### es6 默认传参像pyhon一样 ~~~ 1.为了解决es5那种需要额外的代码来实现默认传参的形式,es6拥有了 和 'python' 一样的使用默认参数的形式 2.通过下面案例,如果想使用的默认参数不是最后一个形参,想让参数调用 其默认参数需要传'undefined' ~~~ ~~~ function test(url, timeout = 2000, callback = function () {}) { // 代码体 } // 使用timeout 和 callback默认参数 test('/foo') // 不使用timeout 和 callback 默认参数 test('/foo', 500, function(body){console.log(body)}) // 使用timeout 默认参数,不使用callback默认参数 test('/foo', undefined, function(body){console.log(body)}) ~~~ >[info] ## arguments -- es6使用默认参数后的arguments >[danger] ##### es5 中的 -- arguments ~~~ 1.通过下面案例可以看出来,es5 时候在非严格模式下,形参改变,则arguments, 会跟着一起变 2.如果是严格模式,arguments只记录第一次传入时候形参值,不会随着后期改变而 改变 ~~~ * 非严格模式 ~~~ function test(first, second) { console.log(first === arguments[0]) console.log(second === arguments[1]) first = 'a' second = 'b' console.log(first === arguments[0]) console.log(second === arguments[1]) } test(1,2) // 打印结果: true true true true ~~~ * 严格模式 ~~~ function test(first, second) { 'use strict' console.log(first === arguments[0]) console.log(second === arguments[1]) first = 'a' second = 'b' console.log(first === arguments[0]) console.log(second === arguments[1]) } test(1,2) // 打印结果: true true false false ~~~ >[danger] ##### es6 中的 -- arguments ~~~ 1.如果函数使用了'es6'的默认参数的形式,无论是否定义严格模式, 'arguments'的长度等于非使用默认参数的形参长度,并且会像es5的 严格模式一样,只会获取第一次别改变的形参值,不会随着接下来的 改变而改变 ~~~ ~~~ function test(first, second=3) { console.log(arguments.length) console.log(first === arguments[0]) console.log(second === arguments[1]) first = 'a' second = 'b' console.log(first === arguments[0]) console.log(second === arguments[1]) } test(1) test(1,2) // 这种没有使用默认参数arguments还是能都取到此时length长度为2 // 打印结果: 1 true false false false ~~~ >[info] ## es6默认参数 -- 调用函数和调用形参使用 ~~~ 1.es6的默认参数不仅仅可以是我们想到数字,字符串,对象,函数 这些类型,也可以是一个被调用的函数,或者其他形参 2. ~~~ >[danger] ##### 调用函数举个例子 ~~~ 1.将调用函数作为默认参数的时候,只有在调用函数时候且使用默认参数, 才会执行形参为被调用函数 ~~~ ~~~ function getValue() { return 5 } // 现在初始化函数getValue() 没有执行 function add(first, second = getValue()) { console.log(first + second) } // 现在没有使用默认参数所以也没有执行getValue() add(1,1) // 这时候才会执行getValue() add(1) ~~~ >[danger] ##### 默认参数为其他形参的默认值 ~~~ 1.可以使用'先定义'的参数作为后定义参数的默认值 2.不可以使用后定义参数作为先定义参数的默认值 ~~~ * 先定义的作为后定义的默认值 ~~~ function add(first, second = first) { console.log(first + second) } add(1) // 2 add(1,1) // 2 ~~~ ~~~ // 也可以这么使用 function add(first, second = getValue(first)) { console.log(first + second) } ~~~ * 不能后定义的作为先定义的默认值 ~~~ 1.默认参数也有临时锁死区的感念,像下面的案例拆解后的效果: let first = second let second = 1 要注意当执行到second的时候,由于TDZ 的缘故导致说second还未被使用 所以在TDZ 中,导致不能后定义的作为先定义的默认值 ~~~ ~~~ function add(first = second, second) { console.log(first + second) } add(undefined,1) // 报错 ~~~ >[info] ## 小技巧只返回一个对象中特定key方法 ~~~ // 返回传入对象参数,指定key的新对象 function pick(object){ // 创建一个没有继承任何原型方法,也就是说它的原型链没有上一层。 let result = Object.create(null) for(let i=1;arguments.length>i;i++){ result[arguments[i]] = object[arguments[i]] } console.log(result) return result } let book = { title:'a', author:'Nic', year:2016 } // 想返回一个 只有'author','year' 的对象 let bookData = pick(book,'author','year') console.log(bookData) // 打印结果: {author: "Nic", year: 2016} ~~~ >[info] ## es6 的不定参数 ~~~ 1.不定参数,字面意思就是不确定要传给函数形参的个数, 表现形式在参数前加(...) 2.注意:每个函数只能有一个不定参数,且不定参数只能在 末尾,对象的字面量setter中不能使用不定参数,因为setter参数 有且只能有一个 3.下面的案例是对上面的案例改造,由于上面的案例使用的是arguments, 所以循环必须从1 开始,现在有了不定参数就可以从0开始 ~~~ ~~~ // 返回传入对象参数,指定key的新对象 function pick(object,...key){ // 创建一个没有继承任何原型方法,也就是说它的原型链没有上一层。 let result = Object.create(null) for(let i=0;key.length>i;i++){ result[key[i]] = object[key[i]] } console.log(result) return result } let book = { title:'a', author:'Nic', year:2016 } // 想返回一个 只有'author','year' 的对象 let bookData = pick(book,'author','year') console.log(bookData) ~~~ * 在es5 没有这种展开运算符的时候使用apply来替代的 ~~~ const arr = ['foo', 'bar', 'baz'] // console.log( // arr[0], // arr[1], // arr[2], // ) // console.log.apply(console, arr) console.log(...arr) ~~~