以下內容摘自--ES6標準入門(阮一峰),純粹為了記憶。 函數參數的預設值 1、基本用法 在ES6之前,不能直接為函數的參數指定預設值,只能採用變通的方法。 如果用戶給參數y賦值false,這時候是不起作用的。並且以上第三個y參數期望輸出空串,但是也變為了World.為了避免這種情況我們可以變為以下 ...
以下內容摘自--ES6標準入門(阮一峰),純粹為了記憶。
函數參數的預設值
1、基本用法
在ES6之前,不能直接為函數的參數指定預設值,只能採用變通的方法。
function log(x,y) { y=y||'World'; console.log(x,y) } log('Hello') //Hello World log('Hello','China')//Hello China log('Hello','')//Hello World
如果用戶給參數y賦值false,這時候是不起作用的。並且以上第三個y參數期望輸出空串,但是也變為了World.為了避免這種情況我們可以變為以下:
if(typeof y==='undefined')
{
y='World';
}
ES6允許為函數的參數設置預設值,即直接寫在參數定義的後面:
function log(x,y='World') { console.log(x,y); } log('Hello')//Hello World log('Hello','China') //Hello China log('Hello','')//Hello
參數變數時預設聲明的,所以不能用let或const再次聲明。
function foo(x=5) { let x=1; //error const x=2;//error }
上面的代碼中,參數變數X是預設聲明的,在函數體中不能用let或const再次聲明,否則會報錯。
2、與解構賦值預設值結合使用
參數預設值可以與解構賦值的預設值結合使用。
function foo({x,y=5}) { console.log(x,y); } foo({})//undefined,5 foo({x:1})//1,5 foo({x:1,y:2})//1,2 foo()//Error
上面的代碼使用了對象的解構賦值預設值,而沒有使用函數參數的預設值。只有當函數foo的參數是一個對象時,變數x和y才會通過解構賦值而生成。如果函數foo調用時參數不是對象,變數x和y就不會生成,從而報錯。
3.參數預設值的位置
通常情況下,定義了預設值的參數應該是函數的尾參數。因為這樣比較容易看出到底省略了哪些參數。如果非尾部的參數設置了預設值,實際上這個參數是無法省略的。
function f(x=1,y) { return[x,y]; } f()//[1,undefined] f(2)//[2,undefined] f(,1)//報錯 f(undefined,1)//[1,1]
如果傳入undefined,將觸發該參數等於預設值,null則沒有這個效果。
function foo(x=5,y=6) { console.log(x,y); } foo(undefined,null)//5,null
4.函數length屬性
(function(a){}).length//1 (function(a=5){}).length//0 (function(a,b,c=5){}).length//2
這是因為length屬性的含義是該函數預期傳入的參數個數。某個參數指定預設值以後,預期傳入的參數個數就不包含這個參數了。同理,rest參數也不會計入length屬性。
如果設置了預設的參數不是尾參數,那麼length屬性也不再計入後面的參數。
(function(a=0,b,c){}).length//0 (function(a,b=1,c)()).length//1
5、作用域
一旦設置了參數的預設值,函數進行聲明初始化時,參數會形成一個單獨的作用域(context).等到初始化結束,這個作用域就會消失。這種語法行為在不設置參數預設值時時不會出現的。
var x=1; function f(x,y=x) { console.log(y); } f(2)//2
上面的代碼中,參數y的預設值等於變數x.調用函數f時,參數形成一個單獨的作用域。在這個作用域裡面,預設值變數x指向第一個參數x,而不是全局變數x,所以輸出是2.
let x=1; function f(y=x) { let x=2; console.log(y); } f()//1
上面的代碼中,函數f調用時,參數y=x形成一個單獨的作用域。在這個作用域裡面,變數x本身沒有定義,所以指向外層的全局變數x.函數調用時,函數體內部的局部變數x影響不到預設值變數x.
如果參數的預設值是一個函數,該函數的作用域也遵守這個規則。
let foo='outer'; function bar(func=x=>foo) { let foo='inner'; console.log(func()); } bar();//outer
函數bar的參數func的預設值是一個匿名函數,返回值為變數foo.函數參數形成的單獨作用域裡面並沒有定義變數foo,所以foo指向外層的全局變數foo,因此輸出outer.
rest參數
ES6引入了rest參數(形式為"...變數名"),用於獲取函數的多餘參數,這樣就不需要使用arguments對象了。rest參數搭配的變數是一個數組,該變數將多餘的參數放入其中。
function add(...values) { let sum=0; for(var val of values) { sum+=val; } return sum; }
add(2,5,3)//10
下麵是一個rest參數代替arguments變數的例子。
function sortNumbers() { return Array.prototype.slice.call(arguments).sort(); } //rest參數的寫法 const sortNumbers=(...numbers)=>numbers.sort();
rest參數中的變數代表一個數組,所以數組特有的方法都可以用於這個變數。
rest參數之後不能再有其他參數(即只能是最後一個參數)。否則會報錯。
name屬性
函數的name屬性返回該函數的函數名。
function foo(){} foo.name//"foo"
ES6對這個屬性的行為做出了一些修改。如果將一個匿名函數賦值給一個變數,ES5的name屬性會返回空字元串,而ES6的name屬性會返回實際的函數名。
var f=function (){}; //ES5 f.name //"" //ES6 f.name //"f"
如果將一個具名函數賦值給一個變數,則ES5和ES6的name屬性都返回這個具名函數原本的名字。
const bar=function baz(){}; //ES5 bar.name //"baz" //ES6 bar.name //"baz"