前言
本文將在上文的基礎上砰左,繼續(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;
再舉個例子,工作中常用到ElementUI庫蝗敢,在自定義一個彈出框時捷泞,使用模板字符串就很方便:
await this.$alert(
`<p><strong>確認是否升級${
this.lectureName
}</strong><br>(若已存在講義套件,升級后請重新生成)</p>`,
{
dangerouslyUseHTMLString: true
}
)
如果覺得文章對你有些許幫助寿谴,歡迎在我的GitHub博客點贊和關注肚邢,感激不盡!