箭頭函數(shù)
- 與函數(shù)表達(dá)式相比,箭頭函數(shù)有更短的語法。
function (i) { return i * 2} //ES5
(i) => i * 2 //ES6
復(fù)雜時需要{}包裹
function (i, j) {
i++
j++
return i + j
} // ES5
(i, j) => {i++, j++, return i + j} // ES6
- 箭頭函數(shù)沒有自身的this,從外層繼承this。
- 箭頭函數(shù)通常是匿名的。
塊級作用域
- ES5中只有全局作用域與函數(shù)作用域,因此內(nèi)層變量將會覆蓋外層變量
- let 提供塊級作用域,let命名的變量只在當(dāng)前塊內(nèi)起作用
- const 聲明的是常量,不可更改
var a = 1
var b = 2
var c = 3
if (true) {
var a = 10 // 函數(shù)作用域
let b = 20 // if塊內(nèi)的作用域
c = 30 // es5解決方法
console.log('a:' + a)
console.log('b:' + b)
console.log('c:' + c)
}
console.log('a:' + a)
console.log('b:' + b)
console.log('c:' + c)
var聲明的變量在循環(huán)時新值會覆蓋舊值,導(dǎo)致輸出的變量都為最終值
var a = []
for (var i = 0; i < 9; i++) {
a[i] = function () {
console.log(i)
}
}
a[2]() // 9
ES5中利用閉包解決這一問題
function test (index) {
var testback = function () {
console.log(index)
}
return testback
}
var a = []
for (var i = 0; i < 9; i++) {
a[i] = test(i)
}
a[2]()
ES6中僅僅使用let即可解決
var a = []
for (let i = 0; i < 9; i++) {
a[i] = function () {
console.log(i)
}
}
a[2]() // 2
const聲明常量
const a = 1
a = 10
console.log(a)
模版字符串
- ES5中,當(dāng)需要插入大量html文檔時需要引用template插件或是用大量‘+’連接
- 模版字符串可直接用'``'標(biāo)識起始
- 模板字符串可以包含嵌入式表達(dá)式,對象字面量,甚至是函數(shù)
var myName = 'xunfeng'
console.log(`your name is ${myName}`) // your name is xunfeng
var people = {
name: 'xunfeng',
age: 20
}
console.log(`your name is ${people.name}, your age is ${people.age}`)
// your name is xunfeng, your age is 20
function fn () {
return 'function'
}
console.log(`可以嵌套函數(shù):${fn()}`)
- 模板字符串可以在表達(dá)式內(nèi)進(jìn)行數(shù)學(xué)運算
var a = 10
var b = 20
console.log(`a+b=${a+b}`) //a+b=30
- 模板字符串內(nèi)保留空格,不需要換行符即可換行
console.log(`第一行
第二行`)
// 第一行
// 第二行
數(shù)值擴展 Numeric Literals
- 支持二進(jìn)制(0b)和八進(jìn)制(0o)新寫法
0b111110111 === 503 // true
0o767 === 503 // true
將二進(jìn)制或八進(jìn)制轉(zhuǎn)換成十進(jìn)制
Number('0b111') // 7
Number('0o10') // 8
- 新的方法
Number.isFinite() // 檢查一個數(shù)值是否為有限
Number.isNaN() // 檢查一個數(shù)值是否為NaN
Number.isInteger() // 檢查一個數(shù)值是否為整數(shù)
Number.EPSILON // 極小的常量,設(shè)定的誤差范圍
- Math對象的擴展
Math.trunc() // 去除一個數(shù)的小數(shù)部分,返回整數(shù)部分
Math.sign() // 判斷一個數(shù)到底是正數(shù)、負(fù)數(shù)、還是零
Math.cbrt() // 用于計算一個數(shù)的立方根
Math.hypot() // 返回所有參數(shù)的平方和的平方根
Math.expm1() // Math.expm1(x)返回ex - 1,即Math.exp(x) - 1
Math.log1p() // Math.log1p(x)方法返回1 + x的自然對數(shù)
Math.log10() // Math.log10(x)返回以10為底的x的對數(shù)
Math.log2() // Math.log2(x)返回以2為底的x的對數(shù)
Math.sinh(x) // 返回x的雙曲正弦(hyperbolic sine)
Math.cosh(x) // 返回x的雙曲余弦(hyperbolic cosine)
Math.tanh(x) // 返回x的雙曲正切(hyperbolic tangent)
Math.asinh(x) // 返回x的反雙曲正弦(inverse hyperbolic sine)
Math.acosh(x) // 返回x的反雙曲余弦(inverse hyperbolic cosine)
Math.atanh(x) // 返回x的反雙曲正切(inverse hyperbolic tangent)
- 指數(shù)運算符 **
console.log(2 ** 3) // 8
對象部分?jǐn)U展
- 變量和函數(shù)可直接作為對象的屬性和方法
<!-- ES6 -->
var object = {
value: 42,
toString() {
return this.value
}
}
console.log(object.toString() === 42) // true
<!-- ES5 -->
var object = {
value: 42,
toString: function toString() {
return this.value
}
}
console.log(object.toString() === 42) // true
- 計算屬性名可以用變量當(dāng)做對象的屬性名
var computed = 'calc'
var comFn = {
[computed + 'xun']: 'hi',
[computed + 'feng']: 'hello'
}
console.log(comFn['calcxun']) // hi
console.log(comFn['calcfeng']) // hello
解構(gòu)
- 允許從數(shù)組或?qū)ο笾刑崛?shù)據(jù)并對變量賦值
var a = 1
var b = 2
var c = {a, b}
console.log(c) // {a: 1, b: 2}
var c = {a: 1, b: 2}
var {a, b} = c
console.log(a, b) // 1 2
默認(rèn)參數(shù) default
- ES6可以指定默認(rèn)參數(shù)在arguments中
function myFn(mes = 'hello') {
console.log(mes)
}
myFn(); // hello
myFn('hi'); // hi
其他參數(shù) rest
- 允許將部分參數(shù)作為一個單獨的數(shù)組
function myFn(a, ...b) {
var result = a
for(let i = 0; i<b.length; i++) {
result += b[i]
}
return result
}
console.log(myFn(1,2,3,4)) // 10
迭代器 iterators && for of
- 可以直接遍歷容器的內(nèi)容
var a=['x', 'y', 'z']
for (let i of a){
console.log(i) // x y z
}
類 classes
- constructor(構(gòu)造方法)
創(chuàng)建實例對象時設(shè)定的屬性 - extends(繼承)
class之間可以通過extends相互繼承,相比于原形鏈更簡潔易懂 - super
在子類constructor中調(diào)用父類的constructor - getter && setter
在Class內(nèi)部可以使用get和set關(guān)鍵字,對某個屬性設(shè)置存值函數(shù)和取值函數(shù),攔截該屬性的存取行為。 - static 靜態(tài)方法
不會被實例對象繼承,只能通過類或類繼承來調(diào)用
class student {
constructor(name, age) {
this.name = name
this.age = age
}
getName () {
console.log(this.name)
}
get myAge() {
return this.age
}
set myAge(value) {
this._age = value
}
static bar() {
console.log('static')
}
}
// 創(chuàng)建實例對象
var xun = new student('xun', 20)
xun.getName() // xun
xun.bar() // TypeError: xun.bar is not a function. (In 'xun.bar()', 'xun.bar' is undefined)
student.bar() // static
// 繼承
class Tom extends student {
constructor(name, age, sex) {
super(name, age)
this.sex = sex
}
}
var tom = new Tom('tom', 20, 'man')
console.log(tom) // 實例對象屬性
tom.myAge = 22
console.log(tom._age) // 22
console.log(tom.myAge) // 20
模塊 modules
- export 暴露對外接口
- import 導(dǎo)入其他模塊接口
<!-- export.js -->
//命名導(dǎo)出
export var foo = ...
export let bar = ...
export const MY_CONST = ...
export function myFunc() {
...
}
export function* myGeneratorFunc() {
...
}
export class MyClass {
...
}
// default 導(dǎo)出
export default 123
export default function (x) {
return x
}
export default x => x;
export default class {
constructor(x, y) {
this.x = x
this.y = y
}
};
//也可以自己列出所有導(dǎo)出內(nèi)容
const MY_CONST = ...
function myFunc() {
...
}
export { MY_CONST, myFunc }
//或者在導(dǎo)出的時候給他們改個名字
export { MY_CONST as THE_CONST, myFunc as theFunc }
//還可以導(dǎo)出從其他地方導(dǎo)入的模塊
export * from 'src/other_module'
export { foo, bar } from 'src/other_module'
export { foo as myFoo, bar } from 'src/other_module'
<!-- import.js -->
// Default exports and named exports
import theDefault, { named1, named2 } from 'src/mylib'
import theDefault from 'src/mylib'
import { named1, named2 } from 'src/mylib'
// Renaming: import named1 as myNamed1
import { named1 as myNamed1, named2 } from 'src/mylib'
// Importing the module as an object
// (with one property per named export)
import * as mylib from 'src/mylib'
// Only load the module, don’t import anything
import 'src/mylib'
參考鏈接
30分鐘掌握ES6/ES2015核心內(nèi)容
ECMAScript 6 入門
ECMAScript 6 equivalents in ES5
如有錯誤,歡迎指正。