現(xiàn)代瀏覽器的迅速支持,促使ES6基本成為業(yè)界標準。我們今天就來聊一下它的這些新特性:
- Let與Const聲明
- 模板字符串
- 對象屬性簡寫
- for...of和for...in
- Symbol數(shù)據(jù)類型
- 解構(gòu)賦值
- Set和Map
- 箭頭函數(shù)
- ES6的擴展
- Promise
- Class類
- 模塊化
一、 Let與Const聲明
傳統(tǒng)var聲明的一大局限是變量污染,比如內(nèi)層變量可能覆蓋外層變量,在if或for循環(huán)中聲明的變量會泄露成全局變量。
為了解決這個問題,ES6引入了let和const命令來進行變量聲明。來看下它們的特點和區(qū)別:
var——會被視為聲明在函數(shù)最頂部,有變量提升特性
let——聲明局部變量,沒有變量提升特性
const——聲明常量,聲明時必須賦值,且一旦賦值就不能再修改,除非const的是一個對象(對象包含的值可以修改,修改方法見下圖)。
const student = { name: 'cc' }
student.name = 'yy';// 不報錯
student = { name: 'yy' };// 報錯
二、模板字符串
將表達式嵌入字符串中進行拼接。只要將變量放在${}內(nèi)即可,整個模板字符串用``包裹起來。
var name = "Lucy", age = 16;
`My name is ${name}, I'm ${age}, I can write like this —— ${name+age}.`
三、對象屬性簡寫
設(shè)置對象屬性時可以不指定屬性名:
const name = 'Ming',
age = '18',
city = 'Shanghai';
const student = {
name,
age,
city
};
console.log(student);
四、for...of和for...in
1、for...of遍歷迭代器,如數(shù)組:
let letters = ['a', 'b', 'c'];
letters.size = 3;
for (let letter of letters) {
console.log(letter); // 結(jié)果: a, b, c
}
2、for...in遍歷對象屬性:
let stus = ["Sam", "22", "男"];
for (let stu in stus) {
console.log(stus[stu]); // 結(jié)果: Sam, 22, 男
}
五、Symbol數(shù)據(jù)類型
用來定義獨一無二的值,通過Symbol('字符串')函數(shù)來生成。如下圖s1和s2,看似一樣實則不同:
let s1 = Symbol('web');
let s2 = Symbol('web');
console.log(s1 === s2);
console.log(typeof s1);
console.log(typeof s2);
因為它的值都不相等,所以可以作為對象屬性名,有三種方式可以實現(xiàn)——直接賦值、[symbol]、defineProperty(),栗子如下:
// 第一種:直接賦值
let symbol = Symbol();
let a = {};
a[symbol] = 'web';
// 第二種:[symbol]屬性
let symbol = Symbol();
let a = {
[symbol]: 'web'
}
// 第三種:defineProperty
let symbol = Symbol();
let a = {};
Object.defineProperty(a, symbol, {value: 'web'});
獲取Symbol屬性,可以使用Object.getOwnPropertySymbols()。
六、解構(gòu)賦值
從數(shù)組或?qū)ο笾刑崛≈?,對變量進行賦值。要求等號兩邊的模式相同。
1、使用方法
- 獲取數(shù)組中的值
var foo = ["one", "two", "three", "four"];
var [one, two] = foo;
console.log(one);
console.log(two);
console.log(three);
var [first, , , last] = foo;
console.log(first);
console.log(last);
var a, b; [a, b] = [1, 2];
console.log(a);
console.log(b);
- 可以方便地交換兩個變量的值
var a = 1;
var b = 3; [a, b] = [b, a];
console.log(a);
console.log(b);
- 獲取對象中的值
const student = {
name: 'Ming',
age: '18',
city: 'Shanghai'
};
const {
name,
age,
city
} = student;
console.log(name);
console.log(age);
console.log(city);
2、需要注意的問題:
- 不能用undefined賦值。
let [x=1] = [undefined];
x; // 1
- 注意變量作用域問題
let x;
{x} = {x: 1}; // 這里的大括號外要加小括號
七、Set和Map
Set類似數(shù)組,Map類似對象,但它們都沒有重復(fù)的值,可以進行去重操作。
1. 聲明方式
new Set();和 new Map();
let a = new Set([1,2,3,4,5]);
let b = new Map([
['name', 'web'],
['des', 'js']
])
2. 共有屬性
(1)constructor:構(gòu)造函數(shù)
(2)size:元素個數(shù),代替數(shù)組的length
3. 操作方法
(1)共有的:delete、has、clear
let a = new Set([1,2,3,4]);
a.delete(2);
console.log(a); // [1,3,4]
console.log(a.has(3)); // true
a.clear(); // Set(0){}
a.add(6);
(2)Set獨有的方法:add()——添加新元素
(3)Map獨有的方法
A. set(key, value)——添加新元素
B. get(key)——查找特定數(shù)值并返回
3. 共有的遍歷方法
- keys()——返回所有鍵
- values()——返回所有值
- entries()——返回鍵值對
- forEach(callbackFn, thisArg)——執(zhí)行callbackFn操作
八、箭頭函數(shù)
箭頭函數(shù)有這樣幾個特點:
1.不需要function關(guān)鍵字,繼承當前上下文的this關(guān)鍵字。
2.只有一個參數(shù)時,可以省略();
3.只返回一個表達式時,可以省略{}和return。
4.沒有arguments變量
5.不會改變this指向——箭頭函數(shù)沒有自己的this,函數(shù)內(nèi)部的this就是外層代碼塊的this,舉個栗子:
var person = {
name: "Lucy",
age: 16,
func: ()=>{
console.log(this);
}
}
person.func(); // window對象
可以發(fā)現(xiàn)this是window對象,如果改為普通函數(shù),this指的就是person對象。
那么是不是箭頭函數(shù)可以完全取代普通函數(shù)呢?
并非如此,定義對象時和需要動態(tài)this時,不能使用箭頭函數(shù)。
九、ES6的擴展
ES6在函數(shù)、對象、數(shù)組對ES5進行了擴展。
1. 函數(shù)擴展
(1)默認值:||后 ---> 參數(shù)定義后
// es5
function log(x,y) {
y = y || 'web';
console.log(x,y);
}
// es6
function log(x,y="web"){
console.log(x,y);
}
(2)剩余運算符: ...arr表示參數(shù)
function web(...arr){
for(let item of arr){
console.log(item);
}
}
web(1,2,3,4,5);
(3)擴展運算符
function add(a,b,c) {
console.log(a);
console.log(b);
console.log(c);
}
var arr = [1,2,3];
add(...arr);
2. 對象的擴展
(1)直接向?qū)ο髮懭胱兞亢秃瘮?shù)作為對象的屬性和方法
(2)可以使用表達式作為對象的屬性
(3)setter和getter
ES6對象的操作方法:
Object.is():比較兩個值是否相等。
Object.assign():用于將對象進行合并。Object.getOwnPropertyDescriptor:返回對象屬性的描述。
Object.keys()返回一個數(shù)組,包含對象自身所有的可枚舉屬性。
3. 數(shù)組的擴展
(1)copyWithin(target,start,end):在當前數(shù)組內(nèi)部,將指定位置的成員復(fù)制到其他位置,然后返回當前數(shù)組。
(2)target——從該位置開始替換數(shù)據(jù)。負值表示倒數(shù)。
(3)start——從該位置開始讀取數(shù)據(jù),默認為0。負值表示倒數(shù)。
(4)end——到該位置前停止讀取數(shù)據(jù),默認等于數(shù)組長度。負值表示倒數(shù)。
(5)find()——找出第一個符合條件的數(shù)組成員。
(6)findIndex()——返回第一個符合條件的數(shù)組成員的位置,都不符合條件則返回-1。
(7)fill()——填充一個數(shù)組,可用于空數(shù)組的初始化。
(8)includes()——數(shù)組是否包含給定值。
4. 字符串的擴展
(1)s.includes(str)——是否找到了str
(2)s.startsWith(str)——str是否在s的開始位置
(3)s.endsWith(str)——str是否在s的結(jié)束位置
它們都支持第2個參數(shù)(整型),表示開始匹配的位置
十、Promise
Promise對象表示異步操作的最終狀態(tài)。它是異步編程的一種解決方案,可以將異步操作用同步操作的流程表達出來,避免層層嵌套,并且提供統(tǒng)一的接口,更方便控制異步操作。
Promise構(gòu)造函數(shù)接收一個函數(shù)作為參數(shù),這個函數(shù)又有兩個參數(shù)分別是resolve和reject,如下:
const promiseObj = new Promise(function(resolve,reject){
// code
if(/*異步操作成功*/){
resolve(value);
}else{
reject(error);
}
})
Promise實例生成后,可以用then方法分別指定resolved狀態(tài)和rejected狀態(tài)的回調(diào)函數(shù)。這兩個回調(diào)函數(shù)都接收Promise對象傳出的值作為參數(shù),其中第一個回調(diào)函數(shù)在Promise對象狀態(tài)變?yōu)閞esolved時調(diào)用,第二個在rejected狀態(tài)時調(diào)用(第二個回調(diào)函數(shù)可選),來段代碼:
promiseObj.then(function(value){},function(error){})
十一、Class類
ES6引入Class類,讓js的面向?qū)ο缶幊谈唵魏鸵子诶斫狻?梢允褂胏lass構(gòu)造對象,二是可以使用extends實現(xiàn)繼承。
class Point{
constructor(x,y){
this.x = x; // 初始化
this.y = y;
}
toString(){
return `(${this.x},${this.y})`;
}
}
let p = new Point(10,20);
console.log(p.x, p.y);
console.log(p.toString());
// 繼承
class ColorPoint extends Point{
constructor(x,y,color){
super(x,y);
this.color = color;
}
showColor(){
console.log('這個點的顏色是'+this.color);
}
}
let cp = new ColorPoint(30,40,'red');
console.log(cp.x, cp.y);
console.log(cp.toString());
cp.showColor();
十二、模塊化
模塊的功能主要由 export 和 import 組成。每個模塊都有自己單獨的作用域,通過 export 來規(guī)定對外暴露的接口,通過import引用其它模塊提供的接口。
1、export導(dǎo)出
可以使用export導(dǎo)出多個變量或函數(shù)
- 導(dǎo)出變量/常量
export var name = 'Rainbow'; // 導(dǎo)出變量
export const sqrt = Math.sqrt; // 導(dǎo)出常量
- 導(dǎo)出多個變量
var name = "Rainbow";
var age = 24;
export {
name,
age
}
- 導(dǎo)出函數(shù)
export function supModule(args){
return args;
}
2、import導(dǎo)入
定義好模塊的輸出以后就可以在另一個模塊引用了。
- 一條import 語句可以同時導(dǎo)入默認函數(shù)和其它變量
import testMethod, {otherMethod} from 'xxx.js';
- 可以為變量起別名
import { otherMethod as om } from 'xxx.js'
十三、其他高級用法
1. Iterator遍歷器
它可以為各種數(shù)據(jù)結(jié)構(gòu)提供統(tǒng)一接口。
2. Genera函數(shù)
也是一種異步編程解決方案,返回一個遍歷器對象,可以依次遍歷Generator函數(shù)的每個狀態(tài)。