ES6 簡介
ECMAScript 6 簡稱 ES6,是 JavaScript 語言的下一代標(biāo)準(zhǔn),已經(jīng)在2015年6月正式發(fā)布了。
ECMAScript 和 JavaScript 的關(guān)系:前者是后者的語法規(guī)格,后者是前者的一種實現(xiàn)。
新特性
-
let 命令聲明的變量
- 不允許重復(fù)聲明
var a = 1;
var a = 2;
console.log(a); //輸出 2
let b = 1;
let b = 2; //報錯
console.log(b) ;
- 塊級作用域
function f1() {
let n = 5;
if (true) {
let n = 10;
console.log(n); //輸出 10
}
console.log(n); // 輸出 5
}
- 不存在變量提升
console.log(a); //輸出 undefined
var a = 1;
console.log(b); //報錯
let b = 1;
-
const 命令聲明的常量
- 塊級作用域。
- 對于簡單類型的數(shù)據(jù)(數(shù)值、字符串、布爾值),值就保存在變量指向的那個內(nèi)存地址,因此等同于常量。
- 但對于復(fù)合類型的數(shù)據(jù)(主要是對象和數(shù)組),變量指向的內(nèi)存地址,所以復(fù)合類型變量中的數(shù)據(jù)是可以改變的。
const s = [5, 6, 7];
s = [1, 2, 3]; // 報錯
s[2] = 45; // 正常工作
console.log(s); // returns [5, 6, 45]
-
Object.freeze
因為const并不能保證復(fù)合類型的數(shù)據(jù)是不可改變的,所以我們需要一個新的命令來保證復(fù)合類型的只讀性,這個命令就是Object.freeze。
let person = {
name:"XiaoMing",
review:"yes"
};
Object.freeze(person);
person.review = "no"; //這條命令將會被忽略,因為此時person對象是只讀的
person.newProp = "age"; // 這條命令也將會被忽略
console.log(obj);
// { name: "XiaoMing", review:"yes"}
-
箭頭函數(shù) (Arrow Functions)
在舊的標(biāo)準(zhǔn)中,我們是這樣書寫函數(shù)的:
const myFunc = function() {
const myVar = "value";
return myVar;
}
使用剪頭函數(shù),我們可以將其簡化為:
const myFunc = () => {
const myVar = "value";
return myVar;
}
還可以進(jìn)一步簡化,我們可以甚至連return都不要:
const myFunc = () => "value"
箭頭函數(shù)可以傳參:
// 將輸入的數(shù)乘以2,并返回
const doubler = (item) => item * 2;
-
展開運算符 (Spread Operator)
-
解構(gòu)賦值(Destructuring Assignment)
-
模板字符串 (Template String)
ES6中引入了一種更強大的字符串寫法,被稱為模板字符串,用反引號( ` )標(biāo)識,用法如下:
const person = {
name: "Zodiac Hasbro",
age: 56
};
//用模板字符串方式書寫的字符串,并將其賦給greeting變量
const greeting = `Hello, my name is ${person.name}!
I am ${person.age} years old.`;
console.log(greeting);
// 輸出:
// Hello, my name is Zodiac Hasbro!
// I am 56 years old.
在上面這段代碼中,有三個地方需要我們注意:
- 模板字符串的標(biāo)識符是反引號(`) 而不是單引號(')。
- 輸出的字符串是多行的,我們在也不需要
\n了。 - 語法
${}可以用來獲取變量,化簡了之前用+來進(jìn)行字符串拼接的寫法。
// es5
var name1 = "bai";
console.log('hello' + name1);
// es6
const name2 = "ming";
console.log(`hello${name2}`);
-
更簡潔的定義對象的方法
//ES5
const person = {
name: "Taylor",
sayHello: function() {
return `Hello! My name is ${this.name}.`;
}
};
//ES6,可以將`function`關(guān)鍵詞省略
const person = {
name: "Taylor",
sayHello() {
return `Hello! My name is ${this.name}.`;
}
};
// ES5
function people(name, age) {
return {
name: name,
age: age
};
}
// ES6
function people(name, age) {
return {
name,
age
};
}
-
class
ES6中提供了一種新的語法創(chuàng)建對象,即使用class關(guān)鍵詞。需要注意的是,這里的class關(guān)鍵詞只是語法糖,并不具有像傳統(tǒng)的面向?qū)ο蟮恼Z言那樣的特性。
在ES5中,我們通常是這樣創(chuàng)建構(gòu)造函數(shù)的:
var Person = function(name){
this.name = name;
}
var person1 = new Person('Jim');
利用class語法糖,我們可以這樣寫:
class Person {
constructor(name){
this.name = name;
}
}
const person1 = new Person('Jim');
在由class定義的對象中,我們添加了構(gòu)造函數(shù)constructor(),構(gòu)造函數(shù)在new被調(diào)用時喚醒,創(chuàng)建一個新的對象。
-
用取值函數(shù)和存值函數(shù)(getters and setters)來封裝對象
在由class定義的對象中,存值函數(shù)和取值函數(shù)現(xiàn)在有了自己的關(guān)鍵字get和set,用法也更加簡單:
class Book {
constructor(author) {
this._author = author;
}
// getter
get writer(){
return this._author;
}
// setter
set writer(updatedAuthor){
this._author = updatedAuthor;
}
}
const lol = new Book('anonymous');
console.log(lol.writer); // anonymous
lol.writer = 'wut';
console.log(lol.writer); // wut
請注意我們調(diào)用存值函數(shù)和取值函數(shù)的方式:lol.writer。這種調(diào)用方式讓他們看起來并不像是函數(shù)。
-
import、export
http://www.itdecent.cn/p/923f642a59af
默認(rèn)情況下,JavaScript中在模塊內(nèi)的所有聲明都是本地的,外部無法訪問。如果需要公開模塊中部分聲明的內(nèi)容,并讓其它模塊加以使用,這個時候就需要導(dǎo)出功能,最簡單的方式是添加export關(guān)鍵字導(dǎo)出模塊。
可以導(dǎo)出的內(nèi)容包括類、函數(shù)以及var、let和const修飾的變量。export命令可以出現(xiàn)在模塊的任何位置,只要處于模塊頂層就可以。如果處于塊級作用域內(nèi),就會報錯,import命令也是如此。
使用export命令定義了模塊的對外接口以后,其他 JS 文件就可以通過import命令加載這個模塊。
import命令具有提升效果,會提升到整個模塊的頭部,首先執(zhí)行。由于import是靜態(tài)執(zhí)行,所以不能使用表達(dá)式和變量,這些只有在運行時才能得到結(jié)果的語法結(jié)構(gòu)。
import后面的from指定模塊文件的位置,可以是相對路徑,也可以是絕對路徑,.js路徑可以省略。如果只是模塊名,不帶有路徑,那么必須有配置文件,告訴 JavaScript 引擎該模塊的位置。
// 全部導(dǎo)入
import people from './example'
// 將整個模塊當(dāng)作單一對象進(jìn)行導(dǎo)入,該模塊的所有導(dǎo)出都會作為對象的屬性存在
import * as example from "./example.js"
console.log(example.name)
console.log(example.getName())
// 導(dǎo)入部分,引入非 default 時,使用花括號
import {name, age} from './example'
// 導(dǎo)出默認(rèn), 有且只有一個默認(rèn)
export default App
// 部分導(dǎo)出
export class App extend Component {};
-
字符串的擴展
includes()
// includes:判斷是否包含然后直接返回布爾值
let str = 'hahah';
console.log(str.includes('y')); // false
repeat()
// repeat: 獲取字符串重復(fù)n次
let s = 'he';
console.log(s.repeat(3)); // 'hehehe'
-
startsWith()
返回布爾值,表示參數(shù)字符串是否在源字符串的頭部; -
endsWith()
返回布爾值,表示參數(shù)字符串是否在源字符串的尾部;
-
數(shù)值的擴展
-
Number.isFinite()
檢查Infinite(是否非無窮)。 -
Number.isNaN()
檢查NaN。 Number.parseInt()-
Number.parseFloat()
ES6將全局方法parseInt()和parseFloat()移植到了Number對象上。這樣是為了逐步減少全局性的方法,使語言逐步模塊化。 -
Number.isInteger()
該方法用來判斷一個值是否為整數(shù)。
-
數(shù)組的擴展
-
Array.from():將類似數(shù)組的對象和可遍歷的對象轉(zhuǎn)為真正的數(shù)組; -
Array.of():將一組數(shù)值轉(zhuǎn)換為數(shù)組,例如:Array.of(3, 11, 8) //[3,11,8] -
fill()方法,使用給定值填充數(shù)組,例如:new Array(3).fill(7) //[7,7,7] - 數(shù)組實例的遍歷。
keys()是對鍵名的遍歷,values()是對鍵值的遍歷,entries()是對鍵值對的遍歷;
-
函數(shù)的擴展
-
為函數(shù)的參數(shù)設(shè)置默認(rèn)值
function greeting(name = "Anonymous") {
return "Hello " + name;
}
console.log(greeting("John")); // 輸出 Hello John
console.log(greeting()); // 輸出 Hello Anonymous
-
rest 參數(shù) (Rest Operator)
ES6中引入了rest參數(shù),其形式為...變量名。通過使用rest參數(shù),你可以向函數(shù)傳入不同數(shù)量的參數(shù):
function howMany(...args) {
return "You have passed " + args.length + " arguments.";
}
console.log(howMany(0, 1, 2)); // 傳入三個參數(shù)
console.log(howMany("string", null, [1, 2, 3], { })); // 傳入四個參數(shù)
rest參數(shù)中的變量代表一個數(shù)組,所有數(shù)組特有的方法都可以用于這個變量:
function push(array, ...items) {
items.forEach(function(item) {
array.push(item);
console.log(item);
});
}
var a = [];
push(a, 1, 2, 3)
console.log(a) //輸出 [1, 2, 3]
rest參數(shù)之后不能再有其他參數(shù),否則程序會報錯。
function add(...values){
let sum = 0;
for(var val of values){
sum += val;
}
return sum;
}
add(2, 5, 3); //10
//add函數(shù)是一個求和函數(shù),利用rest參數(shù)可以向該函數(shù)傳入任意數(shù)目的參數(shù)。
-
擴展運算符
- 擴展運算符,三個點(...),作用是把一個數(shù)組轉(zhuǎn)為用逗號隔開的參數(shù)序列。
console.log(1,...[2,3,4],5);//1 2 3 4 5;
- 擴展運算符替代數(shù)組的apply方法,擴展運算符可以直接把數(shù)組拆開,例如:
//ES5
function f(x,y,z){};
var args = [0,1,2];
f.apply(null, args);
//ES6
function f(x,y,z){};
var args = [0,1,2];
f(...args);
- 擴展運算符提供了數(shù)組合并的新方法:
//ES5
[1,2].concat(more)
//ES6
[1,2, ...more]
-
Promise
用同步的方式去寫異步代碼
// 發(fā)起異步請求
fetch('/api/todos')
.then(res => res.json())
.then(data => ({
data
}))
.catch(err => ({
err
}));