ES6函數(shù)新增內(nèi)容介紹

前言

學(xué)習(xí)函數(shù)新增內(nèi)容扩借,需要先了解ES6的變量解構(gòu)賦值。

本文大量引用阮一峰老師的ES6手冊农曲。

為函數(shù)的參數(shù)設(shè)置默認(rèn)值

function Point(x = 0, y = 0) {
  this.x = x;
  this.y = y;
}

const p = new Point();
console.log(p);

注意事項:

  1. 函數(shù)內(nèi)部不允許給參數(shù)重復(fù)聲明秉馏,比如用var、let唆涝、const聲明找都。但可以重復(fù)賦值。
  2. 參數(shù)默認(rèn)值不是傳值的廊酣,而是每次都重新計算默認(rèn)值表達(dá)式的值能耻,即時從前計算過,也當(dāng)做沒計算過亡驰。也就是說晓猛,參數(shù)默認(rèn)值是惰性求值的。

參數(shù)默認(rèn)值跟解構(gòu)賦值配合使用

首先你要懂ES6變量解構(gòu)賦值凡辱。

下面是利用對象的解構(gòu)賦值戒职,函數(shù)聲明的參數(shù)模式,必須與傳入值的模式匹配:

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() // TypeError: Cannot read property 'x' of undefined 傳入undefined洪燥,模式不匹配,所以報錯

如果想要什么參數(shù)都不傳乳乌,也依然不報錯捧韵,怎么做?依然是利用解構(gòu)賦值汉操,下面代碼中再来,{x, y = 5} = {}表示如果整個參數(shù)不存在,就默認(rèn)為空對象磷瘤,然后再計算x和y各是多少芒篷,x因為沒有對應(yīng)值,當(dāng)然是undefined采缚,y雖然也沒有對應(yīng)值针炉,但是有默認(rèn)值,所以y是5仰担。

function foo({x, y = 5} = {}) {
  console.log(x, y);
}

foo() // undefined 5

對比下面兩段代碼糊识,它們的結(jié)果是一樣的绩社。區(qū)別在哪摔蓝?

寫法一:

  1. 沒有傳參赂苗,所以用默認(rèn)參數(shù),也就是空對象贮尉。
  2. x和y先去空對象尋找對應(yīng)值拌滋,找不到,所以用自己的默認(rèn)值猜谚。

寫法二:

  1. 沒有傳參败砂,所以用默認(rèn)參數(shù){ x: 0, y: 0 }
  2. x和y去{ x: 0, y: 0 }尋找對應(yīng)值魏铅,找到了對應(yīng)值昌犹,所以直接用對應(yīng)值。

區(qū)別就是在哪一步設(shè)默認(rèn)览芳。所以斜姥,在任意一步設(shè)默認(rèn)都可以,只要是合法的js代碼沧竟。

// 寫法一
function m1({x = 0, y = 0} = {}) {
  return [x, y];
}
console.log(m1());

// 寫法二
function m2({x, y} = { x: 0, y: 0 }) {
  return [x, y];
}
console.log(m2());

參數(shù)默認(rèn)值應(yīng)該放到參數(shù)隊列最后面

這么做的目的是可以省略若干傳參铸敏。如果參數(shù)默認(rèn)值排在前面,沒有默認(rèn)值的參數(shù)反而在后面悟泵,那么傳參的寫法就會很不科學(xué)杈笔,比如:

function f(x, y = 5, z) {
  return [x, y, z];
}

怎么傳參?

f() // [undefined, 5, undefined]
f(1) // [1, 5, undefined]
f(1, ,2) // 報錯 這種最簡練的寫法是錯誤的
f(1, undefined, 2) // [1, 5, 2] 這種寫法雖然正確糕非,但是把undefined傳進(jìn)去代碼很丑

所以蒙具,如果參數(shù)有默認(rèn)值就應(yīng)該放到參數(shù)隊列最后面。

參數(shù)默認(rèn)值有特殊作用域

var x = 1;

 // 2作為值傳給x朽肥,由于y = x是完全獨立的作用域禁筏,所以y的值是參數(shù)x的值,也是2
function f(x, y = x) {
  console.log(y); // 打印2
}

f(2) // 2
let x = 1;

 // 沒有傳入值鞠呈,所以y取默認(rèn)值融师,y=x形成獨立作用域,所以y是x的值蚁吝,x指向外層的1旱爆,也就是y是1。
function f(y = x) {
  let x = 2; // 這個x不影響y的值
  console.log(y); // 打印1
}

f() // 1

還有更復(fù)雜的情況窘茁,這里不多介紹了怀伦,更復(fù)雜的情況可能只會出現(xiàn)在面試題里,而實踐中山林,請讓自己的代碼條理清晰房待,這樣對自己,對別人,都有好處桑孩。

參數(shù)默認(rèn)值的一個應(yīng)用

先定義一個通用函數(shù)拜鹤,不干別的,只負(fù)責(zé)報錯:

function throwIfMissing() {
  throw new Error('Missing parameter');
}

然后流椒,其他函數(shù)里面如果有不允許省略的參數(shù)敏簿,就賦值為這個函數(shù):

function throwIfMissing() {
  throw new Error('Missing parameter');
}

function foo(a, b, c = throwIfMissing()) {

}

foo(1,2); // Uncaught Error: Missing parameter

rest參數(shù)

學(xué)習(xí)變量解構(gòu)賦值的時候,我們就遇到了rest變量宣虾,也就是:

let [a, b, ...c] = [1,2,3,4,5,6,7];
console.log(c); // [3,4,5,6,7]

參數(shù)也有這種寫法惯裕,表示剩余的傳參,有多少我全包了绣硝。

function add(...values) {
  let sum = 0;

  for (var val of values) { // values 是一個數(shù)組蜻势,包含所有傳入的參數(shù)
    sum += val;
  }

  return sum;
}

add(2, 5, 3) // 10

所以,到現(xiàn)在鹉胖,傳參真的可以為所欲為握玛,根本不再是ES5時代的參數(shù)必須一對一:

  1. 你有一系列參數(shù),我用比如...args就可以打包次员。
  2. 如果你傳入一個數(shù)組败许,我用解構(gòu)賦值就可以打散。

箭頭函數(shù)

箭頭函數(shù)是ES6對函數(shù)寫法的最大修改淑蔚,改到人們一開始都不認(rèn)識市殷。

var f = v => x;
// 等價于
var f = function(v) {
  return x;
};

代碼塊部分多于一條語句,就要使用大括號將它們括起來刹衫,并且使用return語句返回醋寝。

var sum = (num1, num2) => num1 + num2;
// 等價于
var sum = function(num1, num2) {
  return num1 + num2;
};

由于大括號是被默認(rèn)解釋為代碼塊,所以如果箭頭函數(shù)直接返回一個對象带迟,必須在對象外面加上括號音羞,否則會報錯。

// 報錯
let getTempItem = id => { id: id, name: "Temp" };

// 不報錯
let getTempItem = id => ({ id: id, name: "Temp" });

箭頭函數(shù)可以與變量解構(gòu)結(jié)合使用:

const full = ({ first, last }) => first + ' ' + last;
// 等價于
function full({ first, last }) {
  return first + ' ' + last;
}

// 使用函數(shù)的時候就full({first: 4, last: 8});就可以了

箭頭函數(shù)寫法的優(yōu)勢:

  1. 簡練仓犬。定義一個判斷是偶數(shù)的函數(shù)如下嗅绰,因為這個函數(shù)就是參數(shù)跟運算,所以箭頭函數(shù)很簡練:
const isEven = n => n % 2 == 0;
  1. 簡化回調(diào)函數(shù)搀继。ES5時代窘面,為了清洗的寫回調(diào)函數(shù),往往要折行寫代碼叽躯,現(xiàn)在就簡化了财边。
// 正常函數(shù)寫法
[1,2,3].map(function (x) {
  return x * x;
});

// 箭頭函數(shù)寫法
[1,2,3].map(x => x * x);


// 正常函數(shù)寫法
var result = values.sort(function (a, b) {
  return a - b;
});

// 箭頭函數(shù)寫法
var result = values.sort((a, b) => a - b);

注意,箭頭函數(shù)不是永遠(yuǎn)等價于常規(guī)寫法点骑。區(qū)別如下:

  1. 常規(guī)寫法中酣难,this對象的指向是可變的谍夭,但是在箭頭函數(shù)中,它是固定的憨募。這也是ES6為了降低js學(xué)習(xí)難度所做的改變紧索。常規(guī)寫法中,函數(shù)體內(nèi)的this對象馋嗜,不一定是定義時所在的對象齐板,而是使用時所在的對象吵瞻。但是葛菇,箭頭寫法中,函數(shù)體內(nèi)的this對象橡羞,就是定義時所在的對象眯停,而不是使用時所在的對象。

  2. 不可以當(dāng)作構(gòu)造函數(shù)卿泽,也就是說莺债,不可以使用new命令,否則會拋出一個錯誤签夭。

  3. 不可以使用arguments對象齐邦,該對象在函數(shù)體內(nèi)根本不存在。如果要用第租,可以用 rest 參數(shù)代替措拇。

  4. 不可以使用yield命令,因此箭頭函數(shù)不能用作 Generator 函數(shù)慎宾。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末丐吓,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子趟据,更是在濱河造成了極大的恐慌券犁,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件汹碱,死亡現(xiàn)場離奇詭異粘衬,居然都是意外死亡,警方通過查閱死者的電腦和手機咳促,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門稚新,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人等缀,你說我怎么就攤上這事枷莉。” “怎么了尺迂?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵笤妙,是天一觀的道長冒掌。 經(jīng)常有香客問我,道長蹲盘,這世上最難降的妖魔是什么股毫? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮召衔,結(jié)果婚禮上铃诬,老公的妹妹穿的比我還像新娘。我一直安慰自己苍凛,他們只是感情好趣席,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著醇蝴,像睡著了一般宣肚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上悠栓,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天霉涨,我揣著相機與錄音,去河邊找鬼惭适。 笑死笙瑟,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的癞志。 我是一名探鬼主播往枷,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼今阳!你這毒婦竟也來了师溅?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤盾舌,失蹤者是張志新(化名)和其女友劉穎墓臭,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體妖谴,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡窿锉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了膝舅。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嗡载。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖仍稀,靈堂內(nèi)的尸體忽然破棺而出洼滚,到底是詐尸還是另有隱情,我是刑警寧澤技潘,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布遥巴,位于F島的核電站千康,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏铲掐。R本人自食惡果不足惜拾弃,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望摆霉。 院中可真熱鬧豪椿,春花似錦、人聲如沸携栋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽刻两。三九已至增蹭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間磅摹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工霎奢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留户誓,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓幕侠,卻偏偏與公主長得像帝美,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子晤硕,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 函數(shù)參數(shù)的默認(rèn)值 基本用法 在ES6之前悼潭,不能直接為函數(shù)的參數(shù)指定默認(rèn)值,只能采用變通的方法舞箍。 上面代碼檢查函數(shù)l...
    呼呼哥閱讀 3,389評論 0 1
  • 1.函數(shù)參數(shù)的默認(rèn)值 (1).基本用法 在ES6之前舰褪,不能直接為函數(shù)的參數(shù)指定默認(rèn)值,只能采用變通的方法疏橄。
    趙然228閱讀 690評論 0 0
  • [TOC] 參考阮一峰的ECMAScript 6 入門參考深入淺出ES6 let和const let和const都...
    郭子web閱讀 1,781評論 0 1
  • 第 2 章:函數(shù)基礎(chǔ) 函數(shù)式編程不是僅僅用 function 這個關(guān)鍵詞來編程占拍。如果真這么簡單,那我這本書可以到此...
    iKcamp閱讀 942評論 0 7
  • 函數(shù)和對象 1捎迫、函數(shù) 1.1 函數(shù)概述 函數(shù)對于任何一門語言來說都是核心的概念晃酒。通過函數(shù)可以封裝任意多條語句,而且...
    道無虛閱讀 4,566評論 0 5