概述
????????作為一名軟件工程師,不管你是不是前端開發(fā)的崗位,工作中或多或少都會用到一點(diǎn)JavaScript。JavaScript是大家所了解的語言名稱,但是這個語言名稱是Oracle公司注冊的商標(biāo)。JavaScript的正式名稱是ECMAScript。1996年11月,JavaScript的創(chuàng)造者網(wǎng)景公司將JS提交給國際化標(biāo)準(zhǔn)組織ECMA(歐洲計(jì)算機(jī)制造聯(lián)合會),希望這種語言能夠成為國際標(biāo)準(zhǔn)。隨后,ECMA發(fā)布了規(guī)定瀏覽器腳本語言的標(biāo)準(zhǔn),即ECMAScript,這也有利于這門語言的開放和中立。
????????ES6,全稱ECMAScript 6.0,正式名稱為ECMAScript 2015,是JavaScript的下一個版本標(biāo)準(zhǔn),于2015年6月17日發(fā)布。
????????下面我們了解下ECMAScript的發(fā)展歷程。
????????1997年,ECMAScript 1.0誕生。
????????1998年6月,ECMAScript 2.0誕生,包含一些小的更改,用于同步獨(dú)立的ISO國際標(biāo)準(zhǔn)。
????????1999年12月,ECMAScript 3.0誕生,在業(yè)界得到了廣泛的支持,它奠定了JS的基本語法。
????????2000年的ECMAScript 4.0是ES6的前身,但由于這個版本太過激烈,所以暫時被“和諧”了。
????????2009年12月,ECMAScript 5.0版正式發(fā)布。ECMA專家組預(yù)計(jì)ECMAScript的第五個版本會在2013年中期到2018年作為主流的開發(fā)標(biāo)準(zhǔn)。2011年6月,ES 5.1版發(fā)布,并且成為ISO國際標(biāo)準(zhǔn)。
????????2013年,ES6草案被凍結(jié),不再添加新的功能,新的功能將被放到ES7中。
????????2015年6月,ES6正式通過,成為國際標(biāo)準(zhǔn)。
????????JavaScript ES6提出了很多新的特性,它的目標(biāo)是使得JavaScript語言可以用來編寫復(fù)雜的大型應(yīng)用程序,成為企業(yè)級開發(fā)語言。
????????let關(guān)鍵字
????????let用來聲明局部變量,是塊級作用域。函數(shù)內(nèi)部使用let定義后,對函數(shù)外部無影響,而且有暫時性死區(qū)的約束。
{
let i = 9;
}
// 提示找不到i的錯誤
console.log(i);
let a = 99;
f();
// 輸出:99
console.log(a);
function f() {
// 提示找不到i的錯誤
console.log(a);
let a = 10;
// 輸出:10
console.log(a);
}
const關(guān)鍵字
????????const用來聲明常量,用它定義的變量不可以修改,而且必須初始化。常量的值不能通過重新賦值來改變,并且不能重新聲明。
const foo = {};
foo.prop = 123;
// 其屬性可以修改,正常輸出:123
console.log(foo.prop)
// 報錯,const變量自身不可修改
foo = {};
export/import
????????1、export default向外暴露的成員可以使用任意的變量來接收。在一個模塊中,只能使用export default向外暴露一次。
????????2、使用export向外暴露的成員只能使用 {} 接收,這種情況叫按需導(dǎo)出。一個模塊中可以同時使用多個 export。如果想在引用時改變名稱,可以通過as。
// test.js
export default {
name: 'zs',
age: 10
};
export var title = "小星星";
//main.js
import m1, { title } from './test'
// test2.js
export var title = "小星星";
export var content = '哈哈哈';
// main2.js
import { title, content } from './test2'
import { title as title123, content } from './test2'
import * as test from './test2'
箭頭函數(shù)
????????箭頭函數(shù)相當(dāng)于匿名函數(shù),并且簡化了函數(shù)定義。箭頭函數(shù)有兩種格式:第一種只包含一個表達(dá)式,連{ ... }和return都省略掉了;第二種可以包含多條語句,這時候就不能省略{ ... }和return。
() => 3.14
var double = num => num * 2
(x, y) => x * x + y * y
????????和一般的函數(shù)不同,箭頭函數(shù)不會綁定this,或者說箭頭函數(shù)不會改變this本來的綁定。箭頭函數(shù)內(nèi)部的this是詞法作用域,由上下文確定。
var obj = {
birth: 1990,
getAge: function () {
var b = this.birth; // 1990
var fn = () => new Date().getFullYear() - this.birth;
return fn();
}
};
模板字符串
????????模版字符串,用`(反引號)標(biāo)識,用${}將變量括起來。模板字符串中可以引入變量、反引號自身、js表達(dá)式,還能調(diào)用函數(shù)。如果使用模版字符串表示多行字符串,所有的空格和縮進(jìn)都會被保存在輸出中。
`He is <b>${person.name}</b>and we wish to know his${person.age}.that is all`
console.log( `No matter\` what you do,
I trust you.`);
var x=88;
var y=100;
console.log(`x=${++x},y=${x+y}`);
function test() { return “I like ES6"; }
console.log(`hello, ${test()}`);
默認(rèn)參數(shù)函數(shù)
????????默認(rèn)參數(shù)函數(shù),支持為函數(shù)的參數(shù)提供默認(rèn)值,默認(rèn)參數(shù)必須在所有參數(shù)的最后面。
function greet(name = 'Student', greeting = 'Welcome') {
return `${greeting} ${name}!`;
}
greet();
greet('James');
greet('Richard', 'Howdy');
解構(gòu)
????????解構(gòu),用于從數(shù)組和對象中提取值并賦值給獨(dú)特的變量。
const point = [10, 25, -34];
const [x, y, z] = point;
console.log(x, y, z);
const gemstone = {
type: 'quartz',
color: 'rose',
karat: 21.29
};
const {type, color, karat} = gemstone;
const {type2, color2, karat2} = gemstone;
console.log(type, color, karat);
...展開運(yùn)算符
????????...,用于將數(shù)組序列化,成為逗號隔開的序列。
// 1、獲取數(shù)組最大的值。
Math.max(...[1, 2, 3])
// 2、調(diào)用方法
function sum(a, b){
console.log(a+b)
}
sum(...[2, 3])
// 3、連接數(shù)組
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1.push(...arr2);
// 4、連接數(shù)組
var arr1 = ['a', 'b'];
var arr2 = ['c'];
[...arr1, ...arr2]
// 5、字符串轉(zhuǎn)為真正的數(shù)組
[...'hello'] // [ "h", "e", "l", "l", "o" ]
// 6、擴(kuò)展運(yùn)算法
let map = new Map([ [1, 'one'], [2, 'two'] ]);
let arr = [...map.keys()];
...剩余參數(shù)/可變參數(shù)
????????剩余參數(shù),也用三個連續(xù)的點(diǎn)( ... )表示,可以將多個不定數(shù)量的元素綁定到一個數(shù)組中。
????????可變參數(shù),用于參數(shù)不固定的函數(shù),ES6之前使用參數(shù)對象(arguments)處理。
// 剩余參數(shù)
const order = [20.17, 18.67, 1.50, "cheese", "eggs", "milk", "bread"];
const [total, subtotal, tax, ...items] = order;
console.log(total, subtotal, tax, items);
// 可變參數(shù)
function sum(...nums) {
let total = 0;
for(const num of nums) {
total += num;
}
return total;
}
更簡單的對象字面量
????????ES6使得聲明對象字面量更加簡單,提供了屬性簡寫和方法簡寫功能,屬性名計(jì)算的新特性。
function getInfo(name, age, weight) {
return {
name, age, weight,
['over' + weight]: true,
desc() {
console.log(name, age, weight);
}
};
}
let person = getInfo('Kia', 27, 400);
console.log(person); // {name: "Kia", age: 27, weight: 400, over400: true, desc: ?}
for of
????????for of支持終止循環(huán),也不會遍歷非數(shù)字屬性。
const fruits = ['apple','coconut','mango'];
fruits.fav = 'my favorite fruit';
for(let index in fruits){
console.log(fruits[index]);
}
for(let fruit of fruits){
if(fruit === 'mango' ){
break;
}
console.log(fruit);
}
Map
????????javascript的Object本身就是鍵值對的數(shù)據(jù)結(jié)構(gòu),但實(shí)際上屬性和值構(gòu)成的是”字符串-值“對,屬性只能是字符串。Map提供了”值-值“對的數(shù)據(jù)結(jié)構(gòu),鍵名不僅可以是字符串,也可以是對象。它是一個更完善的Hash結(jié)構(gòu)。
const map1 = new Map();
const objkey = {p1: 'v1'};
map1.set(objkey, 'hello');
console.log(map1.get(objkey));
console.log('%s', map1.size);
const map2 = new Map();
map2.set('a', 4);
console.log('map2: %s', map2.has('a'));
map2.delete('a');
map2.clear();
for (let key of map2.keys()) {
console.log(key);
}
for (let value of map2.values()) {
console.log(value);
}
for (let item of map2.entries()) {
console.log(item[0], item[1]);
}
for (let [key, value] of map2.entries()) {
console.log(key, value);
}
類
????????ES6中的類,與C++、Java中的類有點(diǎn)類似。
????????1、聲明一個類,首先編寫class關(guān)鍵字,緊跟著是類的名字,其他部分的語法類似于對象字面量方法的簡寫形式,但是不需要在子類的各元素之間使用逗號分隔。
????????2、constructor方法是構(gòu)造方法,在實(shí)例化一個類的時候被調(diào)用。constructor方法是必須的,也是唯一的,一個類不能含有多個constructor方法,我們可以在該方法里面自定義一些對象的屬性。
????????3、在類中可以定義類的實(shí)例方法,實(shí)例化后對象可以調(diào)用此方法。
????????4、靜態(tài)方法的定義需要使用static關(guān)鍵字來標(biāo)識,而實(shí)例方法不需要。靜態(tài)方法通過類名來調(diào)用,而實(shí)例方法通過實(shí)例對象來調(diào)用。
????????5、靜態(tài)屬性寫在類定義外面( ES7有新的寫法,直接用static寫在類定義里面即可)。
????????6、必須使用new創(chuàng)建字來創(chuàng)建類的實(shí)例對象。
????????7、必須先聲明定義類,再創(chuàng)建實(shí)例,否則會報錯。
class Animal {
constructor(name){
this.name = name;
}
getName(){
return 'This is a '+this.name;
}
static friends(a1,a2){
return `${a1.name} and ${a2.name} are friends`;
}
}
let dog = new Animal('dog');
console.log(dog.name);
console.log(dog.getName());
let cat = new Animal('cat');
Animal.friends(dog, cat);
繼承
????????1、使用extends關(guān)鍵字來實(shí)現(xiàn)子類(派生類)繼承父類(基類)。派生類中的方法總會覆蓋基類中的同名方法。
????????2、關(guān)鍵字super,相當(dāng)于是父類中的this??梢允褂胹uper來引用父類,訪問父類的方法。
????????3、子類必須在constructor方法中調(diào)用super方法。
????????4、子類的構(gòu)造函數(shù)中,必須先調(diào)用super方法,才可以使用this,否則報錯。
????????5、在子類的普通函數(shù)(非構(gòu)造函數(shù))中訪問父類的函數(shù),可以使用this,也可以使用super。
????????6、在子類中訪問父類的屬性,只能使用this,不能使用super。
????????7、支持內(nèi)建對象的繼承。
class Animal {
constructor(name){
this.name = name;
}
say(){
return `This is a animal`;
}
}
class Dog extends Animal {
constructor(name, color){
super(name);
this.color = color;
}
getDesc(){
return `${super.say()},
name:${this.name},
color:${this.color}`;
}
}
let dog = new Dog("dog", "black");
dog.getDesc();
Web Worker
????????Web Worker的意義在于可以將一些耗時的數(shù)據(jù)處理操作從主線程中剝離,使主線程更加專注于頁面渲染和用戶交互。
// main.js
let worker = new Worker('work.js');
worker.postMessage('Hello World');
worker.postMessage({method: 'echo', args: ['Work']});
worker.onmessage = function (event) {
console.log('Recv msg ' + event.data);
}
worker.terminate();
// work.js
importScripts('script1.js');
self.onmessage = function (event) {
console.log('You said: ' + event.data);
}
self.close();
Promise
????????根據(jù)Promise/A規(guī)范,promise是一個對象,只需要then這一個方法。then方法帶有如下三個參數(shù):成功回調(diào)、失敗回調(diào)、前進(jìn)回調(diào)(規(guī)范沒有要求包括前進(jìn)回調(diào)的實(shí)現(xiàn),但是很多都實(shí)現(xiàn)了)。
????????一個全新的promise對象從每個then的調(diào)用中返回。
????????Promise對象代表一個異步操作,其不受外界影響,有三種狀態(tài):Pending(進(jìn)行中、未完成的)、Resolved(已完成,又稱Fulfilled)、Rejected(已失?。?/p>
function getNumber(){
var p = new Promise(function(resolve, reject){
setTimeout(function(){
var num = Math.ceil(Math.random()*10);
if(num<=5){
resolve(num);
}
else{
reject('數(shù)字太大了');
}
}, 2000);
});
return p;
}
getNumber()
.then(
function(data){
console.log('resolved');
console.log(somedata);
},
function(reason, data){
console.log('rejected');
})
.catch(function(reason){
console.log('rejected');
});
async/await
????????1、async/await是ES7提出的語法,可通過babel在項(xiàng)目中使用。
????????2、async/await是一個用同步思維解決異步問題的方案(等結(jié)果出來之后,代碼才會繼續(xù)往下執(zhí)行)。
????????3、async/await更加語義化,async 是“異步”的簡寫,async function用于申明一個function是異步的;await,可以認(rèn)為是async wait的簡寫,用于等待一個異步方法執(zhí)行完成。
????????4、可以通過多層async function的同步寫法代替?zhèn)鹘y(tǒng)的callback嵌套。
????????5、async自動將常規(guī)函數(shù)轉(zhuǎn)換成Promise,返回值也是一個Promise對象。
????????6、只有async函數(shù)內(nèi)部的異步操作執(zhí)行完,才會執(zhí)行then方法指定的回調(diào)函數(shù)。文章來源:http://www.zghlxwxcb.cn/news/detail-540454.html
????????7、只有async函數(shù)內(nèi)部才可以使用await,在普通函數(shù)內(nèi)使用會報錯。文章來源地址http://www.zghlxwxcb.cn/news/detail-540454.html
function timeout(ms) {
return new Promise((resolve, reject) => {
setTimeout(() => {reject('error')}, ms);
});
}
async function asyncPrint(ms) {
try {
console.log('start');
await timeout(ms);
console.log('end');
} catch(err) {
console.log(err);
}
}
asyncPrint(1000);
async function asyncPrint2(ms) {
console.log('start');
await timeout(ms)
console.log('end');
}
asyncPrint2(1000).catch(err => {
console.log(err);
});
到了這里,關(guān)于軟件工程師,學(xué)習(xí)下JavaScript ES6新特性吧的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!