ECMAScript 6(簡稱ES6)是於2015年6月正式發布的JavaScript語言的標準,正式名為ECMAScript 2015(ES2015)。它的目標是使得JavaScript語言可以用來編寫複雜的大型應用程式,成為企業級開發語言。
另外,一些情況下ES6也泛指ES2015及之後的新增特性,雖然之後的版本應當稱為ES7、ES8等。
基本介紹
- 外文名:ECMAScript 6
- 簡稱:ES6
- 類型:前端語言
- 通過日期:2015年6月
發展歷史
新增功能
聲明命令
{ let a = 10; var b = 1;}console.log(b); // 1console.log(a); // 報錯a沒有定義
for (let i = 0; i < 10; i++) { // ...}console.log(i); // 報錯i沒有定義
var a = [];for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); };}a[6](); // 10var a = [];for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); };}a[6](); // 6
let a = 10;// 即使聲明是var a = 10;後面一樣報錯let a = 1;// 報錯function func(arg) { let arg; // 調用時報錯}function func(arg) { { let arg; // 不報錯,因為對上一個arg來看在子模組中 }}
let i = 123;console.log(i);for (let i = 0; i < 2; i++,console.log(i)) { let i = 'abc'; console.log(i);}// 123// abc// 1// abc// 2
typeof x; // 報錯:同一塊作用域在let x之前,x無法進行任何操作let x;
function text1(){ let n = 5; //或var n = 5; if (true) { let n = 10; } console.log(n); // 5}function text2(){ var n = 5; if (true) { var n = 10; } console.log(n); // 10}function text3(){ let n = 5; if (true) { var n = 10; //報錯,已經聲明了n }}
const PI = 3.1415;PI = 3; //報錯,賦值給常量const a; //報錯,缺少初始化
const foo = {}; // const foo = []同理,可以正常使用push等功能foo.prop = 123; // 為foo添加一個屬性,可以成功console.log(foo.prop); //123foo = {}; // 將foo指向另一個對象,就會報錯
function Point(x, y) { this.x = x; this.y = y;}Point.prototype.toString = function () { return '(' + this.x + ', ' + this.y + ')';};// 上面為原先寫法,下面為ES6的Class寫法class Point { constructor(x, y) { // 構造方法,this關鍵字代表實例對象 this.x = x; this.y = y; } toString() { // 自定義方法,方法之間不需要逗號分隔,加了會報錯 return '(' + this.x + ', ' + this.y + ')'; }}
class Point { constructor() { } toString() { } toValue() { }}console.log(Object.keys(Point.prototype)); // [] 不可枚舉console.log(Object.getOwnPropertyNames(Point.prototype)); // ["constructor", "toString", "toValue"]// 相當於function Point() {}Point.prototype = { constructor() {}, toString() {}, toValue() {},};console.log(Object.keys(Point.prototype)); // ["constructor", "toString", "toValue"]
let methodName = 'getArea';class Square { [methodName]() { }}
const MyClass = class Me { // 如果類的內部沒用到的話,可以省略Me getClassName() { return Me.name; }};let inst = new MyClass();console.log(inst.getClassName()) // MeMe.name // 報錯,Me沒有定義
class Foo { static classMethod() { return 'hello'; }}Foo.classMethod() // 'hello'var foo = new Foo();foo.classMethod() // 報錯foo.classMethod不是一個函式(不存在該方法)
class Foo { static bar () { this.baz(); //等同於調用Foo.baz } static baz () { console.log('hello'); } baz () { console.log('world'); }}Foo.bar() // helloclass Bar extends Foo {}Bar.bar() // hello
// profile.jsexport var firstName = 'Michael';export function f() {};export var year = 1958;//寫法2,與上等同var firstName = 'Michael';function f() {};var y = 1958;export {firstName, f, y as year};
export var foo = 'bar';setTimeout(() => foo = 'baz', 500); // 輸出變數foo,值為bar,500毫秒之後變成bazfunction foo() { export default 'bar' // 語法錯誤}
import {firstName as name, f, year} from './profile.js';import * as p from './profile.js'; function setName(element) { element.textContent = name + ' ' + year; // 值等同於p.firstName + ' ' + p.year;}
import {a} from './xxx.js'; // 也可以是絕對路徑,.js後綴可以省略a.foo = 'hello'; // 合法操作a = {}; // 報錯:a是唯讀的import { 'f' + 'oo' } from '/my_module.js';// 報錯,語法錯誤(不能用運算符)if (x === 1) { import { foo } from 'module1'; // 報錯,語法錯誤(import不能在{}內)} else { import { foo } from 'module2';}
foo();import { foo } from '/my_module.js'; // 不會報錯,因為import的執行早於foo的調用import '/modules/my-module.js'; // 不引入變數,但執行其中全局代碼import { a } from '/modules/my-module.js'; // 重複引入不執行全局代碼,但引入變數a
// export-default.jsexport default function () { console.log('foo');}// import-default.jsimport customName from './export-default.js'; //customName可以是任意名字customName(); // 'foo'
解構賦值
let a = 1;let b = 2;let c = 3;// 等價於let [a, b, c] = [1, 2, 3];let [ , third] = ["foo", "bar", "baz"];third // "bar"let [head, ...tail] = [1, 2, 3, 4];head // 1tail // [2, 3, 4]let [x, y, ...z] = ['a'];x // "a"y // 變數解構不成功,賦值為undefinedz // 數組解構不成功,賦值為[]
let [foo = true] = []; // foo = truelet [x, y = 'b'] = ['a']; // x='a', y='b'let [q = 1, w = 'b'] = ['a', undefined]; // q='a', w='b'let [e = 1] = [null]; // e = null
let { bar, foo } = { foo: "aaa", bar: "bbb" };foo // "aaa"bar // "bbb"let { abc } = { foo: "aaa", bar: "bbb" };abc // undefinedlet { foo: baz } = { foo: 'aaa', bar: 'bbb' };baz // "aaa"const node = { loc: { start: { line: 1, column: 5 } }};let { loc, loc: { start }, loc: { start: { line }} } = node;line // 1loc // Object {start: Object}start // Object {line: 1, column: 5}
//交換變數的值let x = 1;let y = 2;[x, y] = [y, x]; //提取 JSON 數據let jsonData = { id: 42, status: "OK", data: [867, 5309]};let { id, status, data: number } = jsonData;console.log(id, status, number); // 42, "OK", [867, 5309]//遍歷 Map 結構const map = new Map();map.set('first', 'hello');map.set('second', 'world');for (let [key, value] of map) { console.log(key + " is " + value);}// first is hello// second is world
兼容問題
/// 轉碼前input.map(item => item + 1);// 轉碼後input.map(function (item) { return item + 1;});
<script src="https://google.github.io/traceur-compiler/bin/traceur.js"></script><script src="https://google.github.io/traceur-compiler/bin/BrowserSystem.js"></script><script src="https://google.github.io/traceur-compiler/src/bootstrap.js"></script>
//引用外部ES6的js<script type="module"> import './Greeter.js';</script>//直接寫ES6的JS<script type="module"> class Calc { constructor() { console.log('Calc constructor'); } add(a, b) { return a + b; } } var c = new Calc(); console.log(c.add(4,5)); //正常情況下,會在控制台列印出9。</script>
<script> // 創建系統對象 window.System = new traceur.runtime.BrowserTraceurLoader(); // 設定參數 var metadata = { traceurOptions: { experimental: true, properTailCalls: true, symbols: true, arrayComprehension: true, asyncFunctions: true, asyncGenerators: exponentiation, forOn: true, generatorComprehension: true } }; // 載入模組 System.import('./myModule.js', {metadata: metadata}).catch(function(ex) { console.error('Import failed', ex.stack || ex); });</script>