在ES6之前,我們一般用短路表達式處理默認參數
1 function show( a, b ){ 2 var a = a || 10; 3 var b = b || 20; 4 console.log( a, b ); 5 } 6 show( 100, 200 ); //100, 200 7 show(); //10, 20 8 show( 0, 0 ); // 10, 20, 0會被當做false
短路表達式(就是上例中的 || )的運算規則是:
var res = a || 20; 如果a是true 就返回a, 如果a是false就返回20;
上述例子中, 第八行代碼,本意是輸出0, 0, 結果0被當做false, 在傳遞參數0的時候,輸出了后面的默認值。為了嚴謹,我們可以用undefined判斷,如下:
1 function show( a, b ){ 2 var a = typeof a !== 'undefined' ? a : 10; 3 var b = typeof b !== 'undefined' ? b : 20; 4 console.log( a, b ); 5 } 6 show( 100, 200 ); //100,200 7 show( 0, 0 ); //0,0
上述例子默認參數是以前的做法,而es6,提供了類似php的函數默認參數語法.
1 function show( name = 'ghostwu', age = 22, sex = 'man' ){ 2 console.log( name, age, sex ); 3 } 4 show(); //ghostwu, 22, man 使用name, age, sex的默認參數 5 show( 'zhangsan' );//zhangsan, 22, man 使用age和sex的默認參數 6 show( 'zhangsan', 30 );//zhangsan, 30, man 使用sex的默認參數 7 show( 'zhangsan', 40, '男' ); //zhangsan, 40, 男 不使用默認參數
默認參數就是在形式參數后面給他賦一個默認的值.
1 function show( name, age = 22, sex ){ 2 console.log( name, age, sex ); 3 } 4 //函數在沒有傳值得時候,默認為undefined 5 show();//undefined,22,undefined 使用name,age,sex的默認參數 6 7 //函數顯示的傳遞undefined,相當於沒有傳遞參數,所以age用默認值22 8 show( undefined, undefined, undefined ); //undefined,22,undefined 9 10 //函數傳遞null的時候,不會等於undefined,相當於傳null值, 會把age的默認值覆蓋 11 show( undefined, null, undefined ); //undefined, null, undefined
默認參數對arguments會用影響嗎?
1 function show( name, age ){ 2 console.log( name == arguments[0] ); //true 3 console.log( age == arguments[1] ); //true 4 name = 'zhangsan'; 5 age = 30; 6 console.log( name == arguments[0] ); //true 7 console.log( age == arguments[1] ); //true 8 } 9 show( 'ghostwu', 22 );
在es5的非嚴格模式下,參數的值如果在函數中被修改了,同樣會影響(同步)到arguments對象,所以上述結果都是true.
嚴格模式就是在js代碼的最上方加上" use strict", 非嚴格模式自然就是沒有這行代碼
如果使用嚴格模式,參數的值修改之后,就不會影響(同步)到arguments對象
1 "use strict"; 2 function show( name, age ){ 3 console.log( name == arguments[0] ); //true 4 console.log( age == arguments[1] ); //true 5 name = 'zhangsan'; 6 age = 30; 7 console.log( name, age, arguments[0], arguments[1] ); //zhangsan, 30, ghostwu, 22 8 console.log( name == arguments[0] ); //false 9 console.log( age == arguments[1] ); //false 10 } 11 show( 'ghostwu', 22 );
而在采用了默認參數之后,在es6中,不管是否啟用嚴格模式,arguments對象一直保存的是函數調用時候傳遞的參數
1 function show( name, age = 22 ){ 2 console.log( arguments.length ); //1 3 console.log( name === arguments[0] ); //true 4 console.log( age, arguments[1] ); //22, undefined 5 console.log( age === arguments[1] ); //false 6 7 name = 'zhangsan'; 8 age = 30; 9 console.log( name, age, arguments[0], arguments[1] );//zhangsan, 30, ghostwu, undefined 10 console.log( name == arguments[0] ); //false 11 console.log( age == arguments[1] ); //false 12 } 13 show( 'ghostwu' );
默認參數,還可以使用表達式; 允許把前面的參數值賦值給后面的參數, 但是不能把后面的參數賦值給前面的參數
1 function getVal(){ 2 return 10; 3 } 4 function add( a, b = getVal() ){ 5 return a + b; 6 } 7 8 //相當於 a = 100, b = 200 9 console.log( add( 100, 200 ) ); //300 10 //相當於 a = 100, b沒有傳值, 采用getVal()的返回值10 11 console.log( add( 100 ) ); //110
1 let count = 10; 2 3 function getVal(){ 4 return count++; 5 } 6 7 function add( a, b = getVal() ){ 8 return a + b; 9 } 10 11 console.log( add( 100, 200 ) ); //300 12 //count是全局變量,下面這行代碼執行完后 count = 11 13 console.log( add( 100 ) ); //110 14 //相當於a = 100, b = 11 15 console.log( add( 100 ) ); //111
1 function add( a, b = a){ 2 return a + b; 3 } 4 //a = 10 b = 10(a的值) 5 console.log( add( 10 ) ); //20 6 //a = 10 b = 10(傳給b的值) 7 console.log( add( 10, 10 ) ); //20
1 function getVal( val ){ 2 return val + 10; 3 } 4 5 function add( a, b = getVal( a ) ){ 6 return a + b; 7 } 8 9 //a = 10, b = 20 getVal()的返回值 10 console.log( add( 10 ) ); //30 11 //a = 10, b = 30 12 console.log( add( 10, 30 ) ); //40
1 function add( a = b, b ){ 2 return a + b; 3 } 4 // a = 10 b = 20 5 console.log( add( 10, 20 ) ); //30 6 //不能把后面的參數賦給前面的參數 7 console.log( add( undefined, 20 ) ); //報錯