🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] >[success] # 函数形参默认值 ~~~ 在'ES5'函数传递'默认值参数'时候通常大家都会像下面这么写,如果'timeout'和'callback'不传参数, 系统就会默认给'timeout'一个默认值'2000',给'callback'一个空的'function',但是这么写有一个'缺陷', 如果'timeout'传的值为'0'、'undefined'、'null',那么他的默认值都会为'2000',因为数字'0'、'undefined'、 'null'都为'false' ~~~ <br/> >[success] ## 不严谨写法 ~~~ function makeRequest(url, timeout, callback) { timeout = timeout || 2000 callback = callback || function () { } } // 有参数 makeRequest('www.baidu.com', 500, function(){console.log(123)}) // url = 'www.baidu.com' // timeout = 500 // callback = function(){console.log(123)} // 无参数 makeRequest() // url = undefined // timeout = 2000 // callback = function(){} ~~~ <br/> >[success] ## ES5默认参数(严谨写法) ~~~ function makeRequest(url, timeout, callback) { // 这里typeof不可以这样写' typeof timeout !== null ' 因为null是空对象指针,他的类型是对象 timeout = (typeof timeout !== 'undefined' && typeof timeout !== 'object') ? timeout : 2000 callback = (typeof callback !== 'undefined' && typeof callback !== 'object' && typeof callback !== 'number') ? callback : function () { } } makeRequest('www.baidu.com', undefined, null) timeout // 2000 callback // function(){} ~~~ <br/> >[success] ## ES6默认参数写法 ~~~ function makeRequest(url, timeout = 2000, callback = function () { }) { } makeRequest('www.baidu.com', 0, undefined) url // www.baidu.com timeout // 0 callback // function(){} // 如果不传参数就是 undefined , undefined 时就会执行参数默认值, 但是null是空对象指针就会忽略 //默认值,打印出的值为null makeRequest('www.baidu.com', null, undefined) url // www.baidu.com timeout // null callback // function(){} ~~~ <br/> >[success] ## 默认参数值对arguments的影响 ### ES5非严格模式下 ~~~ 在ES5下'a'等于'arguments[0]','b'等于'arguments[1]',但是在'非严格模式下'修改了参数会 '同步更新'到'arguments'对象中,所以修改了'a'和'b'时,'arguments'对象会被重新赋值 ~~~ ~~~ function test(a, b) { console.log(a === arguments[0]) console.log(b === arguments[1]) a = 1 b = 2 console.log(a === arguments[0]) console.log(b === arguments[1]) } test(0, 0) // true // true // true // true ~~~ ### ES5严格模式下 ~~~ 在'严格模式'下修改参数是不会导致'arguments'改变的。 ~~~ ~~~ function test(a, b) { 'use strict' console.log(a === arguments[0]) console.log(b === arguments[1]) a = 1 b = 2 console.log(a === arguments[0]) console.log(b === arguments[1]) } test(0, 0) // true // true // false // false ~~~ ### ES6中的变化 ~~~ 在'ES6'的'默认值参数'的'方法中'无论你在'function'中,是否定义了严格模式(写没写'use strict'), 'ES6'都将以'ES5'的'严格模式'来看待 ~~~ ~~~ function test(a, b = 2) { console.log(arguments.length) console.log(a === arguments[0]) console.log(b === arguments[1]) a = 1 b = 2 console.log(a === arguments[0]) console.log(b === arguments[1]) } test(0) // 1 // true // true // false // false ~~~ <br/> >[success] ## 默认参数表达式( 默认参数小技巧 ) ~~~ '默认参数表达式'更多的'传默认值参数'的'技巧'。 ~~~ <br/> >[success] ### 技巧1( 函数当做默认参数 ) ~~~ 可以把'函数'当做'默认参数',然后在函数中计算后最终返回一个'计算结果'作为'参数',如下: ~~~ ~~~ function c() { return 5 } function getValue(a, b = c()) { return a + b } console.log(getValue(1, 2)) // 3 console.log(getValue(1)) // 6 或者 function getValue(value){ // 用来计算 return value + 5 } function add(a, b = getValue(a)){ return a + b } console.log(add(1)) // 7 console.log(add(1,1)) // 2 ~~~ <br/> >[success] ### 技巧2( 参数1作为参数2的默认参数 ) ~~~ 把'参数1'作为'参数2'的'默认值参数',也可以作为'参数2'的方法的'参数'进行计算 ~~~ ~~~ function add(first, second = first) { return first + second } console.log(add(1)) // 2 console.log(add(1, 1)) // 2 或者 function getValue(value){ // 用来计算 return value + 5 } function add(a, b = getValue(a)){ return a + b } ~~~ <br/> ### 注意 ~~~ 在'引用参数'作为'参数默认值'的时候,只可以'后面参数'引用'前面参数'当做默认值参数, 不可以'前面参数',引用'后面参数'作为'默认值参数',大白话就是'参数2'可以把'参数1',当成自己的 默认值参数,但是'参数1'不可以把'参数2'当做自己的'默认值参数',举例: ~~~ ~~~ function test(a = b, b){ return a + b } console.log(test(1,2)) // 3 console.log(test(undefined,1)) ~~~ ~~~ 因为调用'test(undefined,1)'时候'a'使用'b'作为'参数'时候'b'还'未定义' ~~~ <br/> >[success] ## 默认参数的临时死区 ~~~ 简单来说参数的执行方式和'let、const'一样不存在'变量提升',如果'未定义初始化'就提前使用就会报错。 ~~~ ### 正确写法 ~~~ function test(a, b = a){ return a + b } console.log(test(1,2)) // 3 // 相当于以下代码 let a = 1 let b = 2 console.log(test(1)) // 2 // 相当于以下代码 let a = 1 let b = a ~~~ ### 错误写法 ~~~ function test(a = b, b){ return a + b } console.log(test(1,2)) // 3 // 相当于以下代码 let a = 1 let b = 2 console.log(test(undefined,1)) // 报错 // 相当于以下代码 let a = b let b = 1 ~~~