ES6
ES全稱是ECMAScript主巍,它是由ECMA國(guó)際標(biāo)準(zhǔn)化組織制定的一項(xiàng)腳本語(yǔ)言的規(guī)范化標(biāo)準(zhǔn)
年份 | 版本 |
---|---|
2015年6月 | ES2015 |
2016年6月 | ES2016 |
2017年6月 | ES2017 |
2018年6月 | ES2018 |
... | ... |
ES6其實(shí)是一個(gè)泛指险耀,泛指ES2015及后續(xù)的版本
為什么使用ES6案怯?
每一次標(biāo)準(zhǔn)的誕生都意味著語(yǔ)言的完善,功能的加強(qiáng)江场,JavaScript語(yǔ)言本身也有一些令人不滿意的地方
- 變量提升特性增加了程序運(yùn)行時(shí)的不可預(yù)測(cè)性
- 語(yǔ)法過(guò)于松散纺酸,實(shí)現(xiàn)相同的功能,不同的人可能會(huì)寫出不同的代碼
let
ES6中新增的用于聲明變量的關(guān)鍵字
- 使用
let
聲明的變量具有塊級(jí)作用域(一對(duì){}產(chǎn)生的作用域)- 使用
let
聲明的變量才具有塊級(jí)作用域址否,使用var
聲明的變量不具備塊級(jí)作用域特性
- 使用
if(true) {
let a = 0;
}
console.log(a); // 報(bào)錯(cuò):a is not defined
/* 防止循環(huán)變量成為全局變量 */
for(var i = 0; i < 10; i++) {}
console.log(i); // 10
for(let j = 0; j < 10; j++) {}
console.log(j); // 報(bào)錯(cuò):j is not defined
- 使用
let
聲明的變量不存在變量提升- 只能先聲明再使用
console.log(a); // 報(bào)錯(cuò):a is not defined
let a = 100;
- 使用
let
聲明的變量具有暫時(shí)性死區(qū)特性
var tmp = 123;
if(true) {
console.log(tmp); // 報(bào)錯(cuò):tmp is not defined
let tmp = 20;
}
====================
經(jīng)典面試題
var arr = [];
for(var i = 0; i < 2; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[0]();
arr[1]();
// 此題關(guān)鍵點(diǎn)在于變量i是全局的餐蔬,函數(shù)執(zhí)行時(shí)輸出的都是全局作用域下i的值
let arr = [];
for(let i = 0; i < 2; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[0]();
arr[1]();
// 此題的關(guān)鍵點(diǎn)在于每次循環(huán)都會(huì)產(chǎn)生一個(gè)塊級(jí)作用域碎紊,每個(gè)塊級(jí)作用域中的變量都是不同的,函數(shù)執(zhí)行時(shí)輸出的是自己上一級(jí)(循環(huán)產(chǎn)生的塊級(jí)作用域)作用域下i的值
const
作用:聲明常量樊诺,常量就是值(內(nèi)存地址)不能變的量
- 使用
const
聲明常量具有塊級(jí)作用域
if (true) {
const a = 10;
if (true) {
const a = 20;
console.log(a); // 20
}
console.log(a); // 10
}
console.log(a); // a is not defined
- 使用
const
聲明常量必須賦值(聲明常量時(shí)必須賦初始值)
const a; // Missing initializer in const declaration
- 使用
const
聲明常量仗考,常量賦值后,值不能被修改- 如果值是基本數(shù)據(jù)類型词爬,是不可更改的
- 如果值是引用數(shù)據(jù)類型秃嗜,雖然不能重新賦值,但可以更改數(shù)據(jù)結(jié)構(gòu)內(nèi)部的值
const a = 100;
a = 200; // Assignment to constant variable
const ary = [100,200];
ary[0] = 'a';
ary[1] = 'b';
console.log(ary); // ['a', 'b']
ary = ['a', 'b']; // Assignment to constant variable
let顿膨、const锅锨、var的區(qū)別
- 使用
var
聲明的變量,其作用域?yàn)樵撜Z(yǔ)句所在的函數(shù)內(nèi)恋沃,且存在變量提升現(xiàn)象 - 使用
let
聲明的變量必搞,其作用域?yàn)樵撜Z(yǔ)句所在的代碼塊內(nèi),不存在變量提升 - 使用
const
聲明的是常量芽唇,在后面出現(xiàn)的代碼中不能再修改該常量的值
var |
let |
const |
---|---|---|
函數(shù)級(jí)作用域 | 塊級(jí)作用域 | 塊級(jí)作用域 |
變量提升 | 不存在變量提升 | 不存在變量提升 |
值可更改 | 值可更改 | 值不可更改 |
解構(gòu)賦值
ES6中允許從數(shù)組中提取值顾画,按照對(duì)應(yīng)位置取劫,對(duì)變量賦值匆笤,對(duì)象也可以實(shí)現(xiàn)解構(gòu)
數(shù)組解構(gòu)
let [a, b, c] = [1, 2, 3];
console.log(a);
console.log(b);
console.log(c);
數(shù)組解構(gòu)允許我們按照一一對(duì)應(yīng)的關(guān)系從數(shù)組中提取值,然后將值賦值給變量谱邪,如果解構(gòu)不成功炮捧,變量的值為
undefined
let [foo] = [0]; // foo => undefined
let [bae, foo] = [1]; // bae => 1 foo => undefined
對(duì)象解構(gòu)
let person = { name:'張三', age:20 };
let { name, age } = person;
console.log(name); // '張三'
console.log(age); // 20
對(duì)象解構(gòu)允許我們使用變量的名字匹配對(duì)象的屬性,匹配成功將對(duì)象屬性的值賦值給變量
let person = { name:'張三', age:20 };
let { name: myName, age: myAge} = person; // myName myAge 屬于別名
console.log(myName); // '張三'
console.log(myAge); // 20
箭頭函數(shù)
ES6種新增的定義函數(shù)的方式(箭頭函數(shù)是用來(lái)簡(jiǎn)化函數(shù)定義語(yǔ)法的)
() => {}
const fn = () => {}
- 在箭頭函數(shù)中惦银,如果只有一句代碼咆课,且代碼的執(zhí)行結(jié)果就是返回值,可以省略大括號(hào)
// 傳統(tǒng)函數(shù)定義方式
function sum(x, y) {
return x + y;
}
const result = sum(10, 20);
console.log(result); // 30
// 箭頭函數(shù)定義方式
const sum1 = () => x + y;
const result1 = sum1(10, 20);
console.log(result1); // 30
- 在箭頭函數(shù)中扯俱,如果形參只有一個(gè)书蚪,可以省略小括號(hào)
// 傳統(tǒng)函數(shù)定義方式
function fn(x) {
return x;
}
// 箭頭函數(shù)定義方式
const fn1 = v => v;
- 箭頭函數(shù)不綁定
this
關(guān)鍵字(箭頭函數(shù)沒有自己的this
),箭頭函數(shù)中的this
指向的是函數(shù)定義位置的上下文的this
const obj = {name: '張三' };
function fn() {
console.log(this);
return () => {
console.log(this);
}
}
const resFn = fn.call(obj);
resFn();
var age = 30;
var obj = {
age: 20,
say: () => {
alert(this.age); // 30 對(duì)象是不能產(chǎn)生作用域的,這里的this指向window
}
}
obj.say();
剩余參數(shù)
剩余參數(shù)語(yǔ)法允許我們將一個(gè)不定數(shù)量的參數(shù)表示為一個(gè)數(shù)組
function sum(first, ...args) {
console.log(first); // 10
console.log(args); // [20, 30]
}
sum(10, 20, 30);
const sum = (...args) => {
let total = 0;
args.forEach(item => total += item);
return total;
}
console.log(sum(10, 20)); // 30
console.log(sum(10, 20,30)); // 60
- 剩余參數(shù)和解構(gòu)賦值配合使用
let students = ['張三', '趙四', '王五'];
let [s1, ...s2] = students;
console.log(s1); // '張三'
console.log(s2); // ['趙四', '王五']
擴(kuò)展運(yùn)算符(展開語(yǔ)法)
擴(kuò)展運(yùn)算符可以將數(shù)組或者對(duì)象轉(zhuǎn)為用逗號(hào)分隔的參數(shù)序列
let ary = [1, 2, 3];
// ...ary //=> 1, 2, 3
console.log(...ary); // 1 2 3
console.log(1, 2, 3); // 1 2 3
擴(kuò)展運(yùn)算符的應(yīng)用:擴(kuò)展運(yùn)算符可以應(yīng)用于合并數(shù)組
let ary1 = [1, 2, 3];
let ary2 = [3, 4, 5];
// 方法一
let ary3 = [...ary1, ...ary2];
console.log(ary3); // [1, 2, 3, 3, 4, 5, 6]
// 方法二
ary1.push(...ary2);
console.log(ary1);
擴(kuò)展運(yùn)算符的應(yīng)用:將類數(shù)組或者可遍歷的對(duì)象轉(zhuǎn)換為真正的數(shù)組
let divs = document.getElementsByTagName('div');
console.log(divs);
let ary = [...divs];
console.log(ary);
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
let arr = Array.from(arrayLink); // ['a', 'b', 'c']
// ====================================
// Array.from方法還可以接收第二個(gè)參數(shù)迅栅,作用類似于數(shù)組的map方法殊校,用來(lái)對(duì)每個(gè)元素進(jìn)行處理,將處理后的值放入返回的數(shù)組
let arrayLike = {
'0': 'a',
'1': 'b',
length: 2
};
let arr = Array.from(arrayLink, item => item * 2);
ES6內(nèi)置對(duì)象擴(kuò)展(數(shù)組的擴(kuò)展方法)
-
find()
方法- 用于找出第一個(gè)符合條件的數(shù)組成員读存,如果沒有找到返回
undefined
- 用于找出第一個(gè)符合條件的數(shù)組成員读存,如果沒有找到返回
let ary = [{
id: 1,
name: '張三'
},{
id: 2,
name: '李四'
}];
let target = ary.find((item,index)=>(item.id == 2));
console.log(target);
-
findIndex()
方法- 用于找出第一個(gè)符合條件的數(shù)組成員的位置为流,如果沒有找到返回-1
let ary = [1, 5, 10, 15];
let index = ary.findIndex((value, index) => value > 9);
console.log(index); // 2
-
includes()
方法- 表示某個(gè)數(shù)組是否包含給定的值,返回布爾值
[1, 2, 3].includes(2); // true
[1, 3, 5].includes(6); // false
let ary = ['a', 'b', 'c'];
let result = ary.includes('a');
console.log(result); // true
let result = ary.includes('y');
console.log(result);
模板字符串
ES6新增的創(chuàng)建字符串的方式让簿,使用反引號(hào)定義
let name = `張三`;
console.log(name);
- 模板字符串中可以解析變量
let name = '張三';
let sayHello = `hello,my name is ${name}`; // hello,my name is 張三
console.log(sayHello);
- 模板字符串中可以換行
let result = {
name: '張三',
age: 30,
sex: '男'
}
let html = `<div>
<span>${result.name}</span>
<span>${result.age}</span>
<span>${result.sex}</span>
</div>`;
console.log(html);
- 模板字符串中可以調(diào)用函數(shù)
const sayHello = () => {
return '呵呵';
};
let greet = `${sayHello()}嘿嘿`;
console.log(greet); // 呵呵嘿嘿
ES6內(nèi)置對(duì)象擴(kuò)展(String的擴(kuò)展方法)
-
starsWith()
: 判斷字符串是否以某字符串開頭敬察,返回布爾值 -
endsWith()
: 判斷字符串是否以某字符串結(jié)尾,返回布爾值
let str = `hello world!`;
str.starsWith('hello'); // true
str.endsWith('!'); // true
-
repeat()
方法-
repeat()
方法接收一個(gè)數(shù)字作為參數(shù)尔当,表示將原字符串重復(fù)n次莲祸,返回一個(gè)新字符串
-
'x'.repeat(3); // "xxx"
'hello'.repeat(2); // "hellohello"
數(shù)據(jù)解構(gòu) Set
ES6提供了一種新的數(shù)據(jù)解構(gòu)
Set
,它類似于數(shù)組,但是成員的值都是唯一的,沒有重復(fù)的值
Set
本身是一個(gè)構(gòu)造函數(shù)锐帜,用來(lái)生成Set
數(shù)據(jù)結(jié)構(gòu)
const s = new Set();
// Set函數(shù)可以接收一個(gè)數(shù)組作為參數(shù)藤抡,用來(lái)初始化
const set = new Set([1, 2, 3, 'a', 5, 9]);
console.log(set.size); // => 6
// 數(shù)組去重
const se = new Set(['a', 'b', 'b', 'c']);
console.log(se.size); // 3
const ary = [...se];
console.log(ary); // ['a','b','c']
Set
數(shù)據(jù)結(jié)構(gòu)中的方法
-
add(value)
:添加某個(gè)值,返回Set
結(jié)構(gòu)本身 -
delete(value)
:刪除某個(gè)值抹估,返回一個(gè)布爾值缠黍,表示刪除是否成功 -
has(value)
:返回一個(gè)布爾值,表示該值是否為Set
成員 -
clear()
:清除所有成員药蜻,沒有返回值
const s = new Set();
s.add(1).add(2).add(3); // 向Set結(jié)構(gòu)中添加值
s.delete(2); // 刪除Set結(jié)構(gòu)中的2值 返回布爾值瓷式,表示是否刪除成功
s.has(1); // Set結(jié)構(gòu)中是否有1這個(gè)值,有返回true语泽,沒有返回false
s.clear(); // 清除Set結(jié)構(gòu)中所有的值 沒有返回值
遍歷
Set
結(jié)構(gòu)的實(shí)例與數(shù)組一樣贸典,也擁有forEach
方法,用于對(duì)每個(gè)成員執(zhí)行某種操作踱卵,沒有返回值
s.forEach(value => console.log(value))