ES6核心特性(二)

ES6核心特性

前言

本文將在上文的基礎上砰左,繼續(xù)介紹ES6核心特性:箭頭函數(shù)、rest參數(shù)场航、擴展運算符缠导、解構賦值以及模板字符串,希望對大家有些許幫助旗闽!

如果你想了解塊作用域酬核、promise、class以及ES6環(huán)境配置适室,請猛戳ES6核心特性(一)

一嫡意、箭頭函數(shù)

ES6 允許使用“箭頭”(=>)定義函數(shù)。它主要有兩個作用:縮減代碼和改變this指向捣辆,接下來我們詳細介紹:

1. 縮減代碼

const double1 = function(number){
   return number * 2;   //ES5寫法
}
const double2 = (number) => {
 return number * 2;    //ES6寫法
}
const double4 = number => number * 2; //可以進一步簡化

多個參數(shù)記得加括號

 const double6 = (number,number2) => number + number2;

如果箭頭函數(shù)的代碼塊部分多于一條語句蔬螟,就要使用大括號將它們括起來,并且使用return語句返回汽畴。

 const double = (number,number2) => {
   sum = number + number2 
   return sum;
 }

由于大括號被解釋為代碼塊旧巾,所以如果箭頭函數(shù)直接返回一個對象,必須在對象外面加上括號忍些,否則會報錯鲁猩。

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

此外還有個好處就是簡化回調函數(shù)

// 正常函數(shù)寫法
[1,2,3].map(function (x) {
  return x * x;
});
// 箭頭函數(shù)寫法
[1,2,3].map(x => x * x);//[1, 4, 9]

2. 改變this指向

長期以來,JavaScript 語言的this對象一直是一個令人頭痛的問題罢坝,在對象方法中使用this廓握,必須非常小心。箭頭函數(shù)”綁定”this嘁酿,很大程度上解決了這個困擾隙券。我們不妨先看一個例子:

const team = {
  members:["Henry","Elyse"],
  teamName:"es6",
  teamSummary:function(){
    return this.members.map(function(member){
      return `${member}隸屬于${this.teamName}小組`;    // this不知道該指向誰了
    })
  }
}
console.log(team.teamSummary());//["Henry隸屬于undefined小組", "Elyse隸屬于undefined小組"]

teamSummary函數(shù)里面又嵌了個函數(shù),這導致內部的this的指向發(fā)生了錯亂闹司。
那如何修改:

方法一娱仔、let self = this

const team = {
  members:["Henry","Elyse"],
  teamName:"es6",
  teamSummary:function(){
    let self = this;
    return this.members.map(function(member){
      return `${member}隸屬于${self.teamName}小組`;
    })
  }
}
console.log(team.teamSummary());//["Henry隸屬于es6小組", "Elyse隸屬于es6小組"]

方法二、bind函數(shù)

const team = {
  members:["Henry","Elyse"],
  teamName:"es6",
  teamSummary:function(){
    return this.members.map(function(member){
      // this不知道該指向誰了
      return `${member}隸屬于${this.teamName}小組`;
    }.bind(this))
  }
}
console.log(team.teamSummary());//["Henry隸屬于es6小組", "Elyse隸屬于es6小組"]

方法三游桩、 箭頭函數(shù)

const team = {
  members:["Henry","Elyse"],
  teamName:"es6",
  teamSummary:function(){
    return this.members.map((member) => {
      // this指向的就是team對象
      return `${member}隸屬于${this.teamName}小組`;
    })
  }
}
console.log(team.teamSummary());//["Henry隸屬于es6小組", "Elyse隸屬于es6小組"]

3.使用注意點

(1)函數(shù)體內的this對象牲迫,就是定義時所在的對象,而不是使用時所在的對象众弓。

(2)不可以當作構造函數(shù)恩溅,也就是說,不可以使用new命令谓娃,否則會拋出一個錯誤脚乡。

(3)不可以使用arguments對象,該對象在函數(shù)體內不存在滨达。如果要用奶稠,可以用 rest 參數(shù)代替。

(4)不可以使用yield命令捡遍,因此箭頭函數(shù)不能用作 Generator 函數(shù)锌订。

二、rest 參數(shù)

ES6 引入 rest 參數(shù)(形式為...變量名)画株,用于獲取函數(shù)的多余參數(shù)辆飘,這樣就不需要使用arguments對象了啦辐。

rest 參數(shù)搭配的變量是一個數(shù)組,該變量將多余的參數(shù)放入數(shù)組中蜈项。
我們舉個例子:如何實現(xiàn)一個求和函數(shù)芹关?

傳統(tǒng)寫法:

function addNumbers(a,b,c,d,e){
  var numbers = [a,b,c,d,e];
  return numbers.reduce((sum,number) => {
    return sum + number;
  },0)
 }
 console.log(addNumbers(1,2,3,4,5));//15

ES6寫法:

 function addNumbers(...numbers){
  return numbers.reduce((sum,number) => {
    return sum + number;
  },0)
 }
 console.log(addNumbers(1,2,3,4,5));//15

也可以與解構賦值組合使用

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

rest 參數(shù)還可以與箭頭函數(shù)結合

const numbers = (...nums) => nums;
numbers(1, 2, 3, 4, 5)// [1,2,3,4,5]  

注意:①每個函數(shù)最多只能聲明一個rest參數(shù),而且 rest參數(shù)必須是最后一個參數(shù)紧卒,否則報錯侥衬。

②rest參數(shù)不能用于對象字面量setter之中

let object = {
    set name(...value){   //報錯
        //執(zhí)行一些邏輯
    }
}

三、展開運算符

與剩余參數(shù)關聯(lián)最密切的就是擴展運算符跑芳。剩余參數(shù)允許你把多個獨立的參數(shù)合并到一個數(shù)組中轴总;而擴展運算符則允許將一個數(shù)組分割,并將各個項作為分離的參數(shù)傳給函數(shù)博个。

當用在字符串或數(shù)組前面時稱為擴展運算符,個人覺得可以理解為rest參數(shù)的逆運算怀樟,用于將數(shù)組或字符串進行拆解。有些時候盆佣,函數(shù)不允許傳入數(shù)組漂佩,此時使用展開運算符就很方便,不信的話罪塔,咱們看個例子:Math.max()方法投蝉,它接受任意數(shù)量的參數(shù),并會返回其中的最大值征堪。

let value1 = 25,                
let value2 = 50;
console.log(Math.max(value1, value2));  //  50

但若想處理數(shù)組中的值瘩缆,此時該如何找到最大值?Math.max()方法并不允許你傳入一個數(shù)組佃蚜。其實你可以像使用rest參數(shù)那樣在該數(shù)組前添加...,并直接將其傳遞給 Math.max()

let values = [25,50,75, 100]
//等價于console.log(Math.max(25,50,75,100));
console.log(Math.max(...values));   //100

擴展運算符還可以與其他參數(shù)混用

let values = [-25,-50,-75,-100]
console.log(Math.max(...values,0)); //0

擴展運算符拆解字符串與數(shù)組

var array = [1,2,3,4,5];
console.log(...array);//1 2 3 4 5
var str = "String";
console.log(...str);//S t r i n g

還可以實現(xiàn)拼接

var defaultColors = ["red","greed"];
var favoriteColors = ["orange","yellow"];
var fallColors = ["fire red","fall orange"];
console.log(["blue","green",...fallColors,...defaultColors,...favoriteColors]
//["blue", "green", "fire red", "fall orange", "red", "greed", "orange", "yellow"]

四庸娱、解構賦值----更方便的數(shù)據(jù)訪問

ES6 新增了解構,這是將一個數(shù)據(jù)結構分解為更小的部分的過程谐算。

1.解構為何有用熟尉?

在ES5及更早版本中,從對象或數(shù)組中獲取信息洲脂、并將特定數(shù)據(jù)存入本地變量斤儿,需要書寫許多并且相似的代碼。例如:

 var expense = {
   type: "es6",
   amount:"45"
 };
 var type = expense.type;
 var amount = expense.amount;
 console.log(type,amount);

此代碼提取了expense對象的type與amount值恐锦,并將其存在同名的本地變量上往果。雖然 這段代碼看起來簡單,但想象一下若有大量變量需要處理一铅,你就必須逐個為其賦值陕贮;并且若有一個嵌套的數(shù)據(jù)結構需要遍歷以尋找信息,你可能會為了一點數(shù)據(jù)而挖掘整個結構潘飘。

這就是ES6為何要給對象與數(shù)組添加解構肮之。當把數(shù)據(jù)結構分解為更小的部分時掉缺,從中提取你要的數(shù)據(jù)會變得容易許多。

2.對象

上個例子中如果采用對象解構的方法戈擒,就很容易獲取expense對象的type與amount值攀圈。

const { type,amount } = expense;
console.log(type,amount);

我們再來看個例子:

let node = {type:"Identifier",  name:"foo"},    
type = "Literal",name = 5;
({type,name}= node);//  使用解構來分配不同的值 
console.log(type); //   "Identifier" 
console.log(name); //   "foo"

注意:你必須用圓括號包裹解構賦值語句,這是因為暴露的花括號會被解析為代碼塊語句峦甩,而塊語句不允許在賦值操作符(即等號)左側出現(xiàn)。圓括號標示了里面的花括號并不是塊語句现喳、而應該被解釋為表達式凯傲,從而允許完成賦值操作。

默認值:
可以選擇性地定義一個默認值嗦篱,以便在指定屬性不存在時使用該值冰单。若要這么做,需要在 屬性名后面添加一個等號并指定默認值灸促,就像這樣:

let node = {
  type: "Identifier",
  name: "foo"
};
let {
  type,
  name,
  value = true
} = node;
console.log(type); //   "Identifier" 
console.log(name); //   "foo" 
console.log(value); //  true

嵌套對象解構:
使用類似于對象字面量的語法诫欠,可以深入到嵌套的對象結構中去提取你想要的數(shù)據(jù)。

let node = {
  type: "Identifier",
  name: "foo",
  loc: {
    start: {
      line: 1,
      column: 1
    },
    end: {
      line: 1,
      column: 4
    }
  }
};
let { loc: { start }} = node;
console.log(start.line); // 1 
console.log(start.column); //   1

本例中的解構模式使用了花括號浴栽,表示應當下行到node對象的loc屬性內部去尋找start屬性荒叼。

必須傳值的解構參數(shù)

function setCookie(name, value, {
  secure,
  path,
  domain,
  expires
}) {
  //    設置cookie的代碼 
}
  setCookie("type", "js");//報錯

在此函數(shù)內,name與value參數(shù)是必需的典鸡,而secure被廓、path、domain與expires則不是萝玷。默認情況下調用函數(shù)時未給參數(shù)解構傳值會拋出錯誤嫁乘。像上例中如果setCookie不傳第三個參數(shù),就會報錯球碉。若解構參數(shù)是可選的蜓斧,可以給解構的參數(shù)提供默認值來處理這種錯誤。

function setCookie(name, value, {
  secure,
  path,
  domain,
  expires
} = {}) {}
setCookie("type", "js");//不會報錯

3.數(shù)組

const names = ["Henry","Bucky","Emily"];
const [name1,name2,name3] = names;
console.log(name1,name2,name3);//Henry Bucky Emily
const [name,...rest] = names;//結合展開運算符
console.log(rest);//["Bucky", "Emily"]

用{}解構返回數(shù)組個數(shù)

const {length} = names;
console.log(length);//3

數(shù)組解構也可以用于賦值上下文睁冬,但不需要用小括號包裹表達式挎春。這點跟對象解構的約定不同。

let colors = ["red", "green", "blue"],
  firstColor = "black",
  secondColor = "purple";
[firstColor, secondColor] = colors;
console.log(firstColor); // "red" 
console.log(secondColor);   // "green"

默認值:數(shù)組解構賦值同樣允許在數(shù)組任意位置指定默認值豆拨。當指定位置的項不存在搂蜓、或其值為undefined,那么該默認值就會被使用辽装。

let colors = ["red"];
let [firstColor, secondColor = "green"] = colors;
console.log(firstColor); // "red" 
console.log(secondColor);// "green"

與rest參數(shù)搭配

在ES5中常常使用concat()方法來克隆數(shù)組帮碰,例如:

//在ES5中克隆數(shù)組 
var colors = ["red", "green", "blue"];
var clonedColors = colors.concat();
console.log(clonedColors); //"[red,green,blue]"

在ES6中,你可以使用剩余項的語法來達到同樣效果

//在ES6中克隆數(shù)組 
let colors = ["red", "green", "blue"];
let [...clonedColors] = colors;
console.log(clonedColors); //[red,green,blue]

接下我們看個例子:如何將數(shù)組轉化為對象

const points = [
  [4,5],
  [10,1],
  [0,40]
];
//期望得到的數(shù)據(jù)格式如下拾积,如何實現(xiàn)殉挽?
// [
//   {x:4,y:5},
//   {x:10,y:1},
//   {x:0,y:40}
// ]
let newPoints = points.map(pair => {
  const [x,y] = pair;
  return {x,y}
})
//還可以通過以下辦法丰涉,更為簡便
let newPoints = points.map(([x,y]) => {
  return {x,y}
})
console.log(newPoints);

混合解構

const people = [
  {name:"Henry",age:20},
  {name:"Bucky",age:25},
  {name:"Emily",age:30}
];
//es5 寫法 
var age = people[0].age;
console.log(age);
//es6 解構
const [age] = people;
console.log(age);//第一次解構數(shù)組 {name:"Henry",age:20}
const [{age}] = people;//再一次解構對象
console.log(age);//20

4.注意點

當使用解構來配合var、let斯碌、const來聲明變量時一死,必須提供初始化程序(即等號右邊的值)。下面的代碼都會因為缺失初始化程序而拋出語法錯誤:

var { type, name };//   語法錯誤傻唾! 
let { type, name };//   語法錯誤投慈!
const { type, name };// 語法錯誤!

五冠骄、模板字符串(template string)

模板字符串是增強版的字符串伪煤,用反引號(`)標識。它可以當作普通字符串使用凛辣,也可以用來定義多行字符串抱既,或者在字符串中嵌入變量。
模板字符串中嵌入變量和函數(shù)扁誓,需要將變量名寫在${}之中防泵。

let name = "Henry";
function makeUppercase(word){
  return word.toUpperCase();
}
let template = 
  `
  <h1>${makeUppercase('Hello')}, ${name}!</h1>//可以存放函數(shù)和變量
  <p>感謝大家收看我們的視頻, ES6為我們提供了很多遍歷好用的方法和語法!</p>
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
  </ul>
  `;
document.getElementById('template').innerHTML = template;
image

再舉個例子,工作中常用到ElementUI庫蝗敢,在自定義一個彈出框時捷泞,使用模板字符串就很方便:

   await this.$alert(
          `<p><strong>確認是否升級${
            this.lectureName
          }</strong><br>(若已存在講義套件,升級后請重新生成)</p>`,
          {
            dangerouslyUseHTMLString: true
          }
        )

如果覺得文章對你有些許幫助寿谴,歡迎在我的GitHub博客點贊和關注肚邢,感激不盡!

參考文章

ECMAScript 6 入門

深入理解ES6

ES6的rest參數(shù)和擴展運算符

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末拭卿,一起剝皮案震驚了整個濱河市骡湖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌峻厚,老刑警劉巖响蕴,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異惠桃,居然都是意外死亡浦夷,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門辜王,熙熙樓的掌柜王于貴愁眉苦臉地迎上來劈狐,“玉大人,你說我怎么就攤上這事呐馆》实蓿” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵汹来,是天一觀的道長续膳。 經常有香客問我改艇,道長,這世上最難降的妖魔是什么坟岔? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任谒兄,我火速辦了婚禮,結果婚禮上社付,老公的妹妹穿的比我還像新娘承疲。我一直安慰自己,他們只是感情好鸥咖,可當我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布燕鸽。 她就那樣靜靜地躺著,像睡著了一般扛或。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上碘饼,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天熙兔,我揣著相機與錄音,去河邊找鬼艾恼。 笑死住涉,一個胖子當著我的面吹牛,可吹牛的內容都是我干的钠绍。 我是一名探鬼主播舆声,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼柳爽!你這毒婦竟也來了媳握?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤磷脯,失蹤者是張志新(化名)和其女友劉穎蛾找,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體赵誓,經...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡打毛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了俩功。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片幻枉。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖诡蜓,靈堂內的尸體忽然破棺而出熬甫,到底是詐尸還是另有隱情,我是刑警寧澤蔓罚,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布罗珍,位于F島的核電站洽腺,受9級特大地震影響,放射性物質發(fā)生泄漏覆旱。R本人自食惡果不足惜蘸朋,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望扣唱。 院中可真熱鬧藕坯,春花似錦、人聲如沸噪沙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽正歼。三九已至辐马,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間局义,已是汗流浹背喜爷。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留萄唇,地道東北人檩帐。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像另萤,于是被迫代替她去往敵國和親湃密。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內容

  • 三四敞,字符串擴展 3.1 Unicode表示法 ES6 做出了改進泛源,只要將碼點放入大括號,就能正確解讀該字符忿危。有了這...
    eastbaby閱讀 1,537評論 0 8
  • [TOC] 參考阮一峰的ECMAScript 6 入門參考深入淺出ES6 let和const let和const都...
    郭子web閱讀 1,781評論 0 1
  • 一俩由、ES6簡介 ? 歷時將近6年的時間來制定的新 ECMAScript 標準 ECMAScript 6(亦稱 ...
    一歲一枯榮_閱讀 6,078評論 8 25
  • 今晚接觸到了倆歌手:原子邦尼,周興哲癌蚁。 邦尼的電音聽著是搖滾的治愈幻梯,不同于以往失戀的慢情歌。有點像分手后的...
    X_390a閱讀 212評論 0 1
  • 昨天看朱麗姐寫得 《和自己和解》煞躬,我淚流滿面,因為從她的描述中我看到了自己的影子!當朱麗姐寫到當別人說她的...
    盼盼_9ba9閱讀 443評論 2 1