以下內容摘自--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"
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/157947.html
標籤:JavaScript
上一篇:原生JS輪播圖
