如下內容摘自--ES6標準入門(阮一峯),純粹爲了記憶。數組
函數參數的默認值函數
一、基本用法spa
在ES6以前,不能直接爲函數的參數指定默認值,只能採用變通的方法。prototype
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.爲了不這種狀況咱們能夠變爲如下:rest
if(typeof y==='undefined')code
{對象
y='World';blog
}作用域
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再次聲明,不然會報錯。
二、與解構賦值默認值結合使用
參數默認值能夠與解構賦值的默認值結合使用。
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
五、做用域
一旦設置了參數的默認值,函數進行聲明初始化時,參數會造成一個單獨的做用域(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"