溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

es6的新特性是什么

發(fā)布時間:2021-03-02 11:45:54 來源:億速云 閱讀:240 作者:小新 欄目:web開發(fā)

這篇文章將為大家詳細(xì)講解有關(guān)es6的新特性是什么,小編覺得挺實(shí)用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

es6新特性:const與let變量、模板字面量、解構(gòu)、增強(qiáng)的對象字面量、for...of循環(huán)、展開運(yùn)算符(...)、剩余參數(shù)(可變參數(shù))、ES6箭頭函數(shù)、類的支持、字符串模板、iterator、generator、模塊、Symbols等。

const 與 let 變量

使用var帶來的麻煩:

function getClothing(isCold) {
  if (isCold) {
    var freezing = 'Grab a jacket!';
  } else {
    var hot = 'It's a shorts kind of day.';
    console.log(freezing);
  }
}

運(yùn)行getClothing(false)后輸出的是undefined,這是因?yàn)閳?zhí)行function函數(shù)之前,所有變量都會被提升, 提升到函數(shù)作用域頂部.

letconst聲明的變量解決了這種問題,因?yàn)樗麄兪菈K級作用域, 在代碼塊(用{}表示)中使用letconst聲明變量, 該變量會陷入暫時性死區(qū)直到該變量的聲明被處理.

function getClothing(isCold) {
  if (isCold) {
    const freezing = 'Grab a jacket!';
  } else {
    const hot = 'It's a shorts kind of day.';
    console.log(freezing);
  }
}

運(yùn)行getClothing(false)后輸出的是ReferenceError: freezing is not defined,因?yàn)?freezing 沒有在 else 語句、函數(shù)作用域或全局作用域內(nèi)聲明,所以拋出 ReferenceError。

關(guān)于使用letconst規(guī)則:

  • 使用let聲明的變量可以重新賦值,但是不能在同一作用域內(nèi)重新聲明

  • 使用const聲明的變量必須賦值初始化,但是不能在同一作用域類重新聲明也無法重新賦值.

es6的新特性是什么
es6的新特性是什么

模板字面量

在ES6之前,將字符串連接到一起的方法是+或者concat()方法,如

const student = {
  name: 'Richard Kalehoff',
  guardian: 'Mr. Kalehoff'
};
const teacher = {
  name: 'Mrs. Wilson',
  room: 'N231'
}
let message = student.name + ' please see ' + teacher.name + ' in ' + teacher.room + ' to pick up your report card.';

模板字面量本質(zhì)上是包含嵌入式表達(dá)式的字符串字面量.
模板字面量用倒引號 ( `` )(而不是單引號 ( '' ) 或雙引號( "" ))表示,可以包含用 ${expression} 表示的占位符

let message = `${student.name} please see ${teacher.name} in ${teacher.room} to pick up your report card.`;

解構(gòu)

在ES6中,可以使用解構(gòu)從數(shù)組和對象提取值并賦值給獨(dú)特的變量

解構(gòu)數(shù)組的值:

const point = [10, 25, -34];
const [x, y, z] = point;
console.log(x, y, z);

Prints: 10 25 -34

[]表示被解構(gòu)的數(shù)組, x,y,z表示要將數(shù)組中的值存儲在其中的變量, 在解構(gòu)數(shù)組是, 還可以忽略值, 例如const[x,,z]=point,忽略y坐標(biāo).

解構(gòu)對象中的值:

const gemstone = {
  type: 'quartz',
  color: 'rose',
  karat: 21.29
};
const {type, color, karat} = gemstone;
console.log(type, color, karat);

花括號 { } 表示被解構(gòu)的對象,type、colorkarat 表示要將對象中的屬性存儲到其中的變量

對象字面量簡寫法

let type = 'quartz';
let color = 'rose';
let carat = 21.29;
const gemstone = {
  type: type,
  color: color,
  carat: carat
};
console.log(gemstone);

使用和所分配的變量名稱相同的名稱初始化對象時如果屬性名稱和所分配的變量名稱一樣,那么就可以從對象屬性中刪掉這些重復(fù)的變量名稱。

let type = 'quartz';
let color = 'rose';
let carat = 21.29;
const gemstone = {type,color,carat};
console.log(gemstone);

簡寫方法的名稱:

const gemstone = {
  type,
  color,
  carat,
  calculateWorth: function() {
    // 將根據(jù)類型(type),顏色(color)和克拉(carat)計(jì)算寶石(gemstone)的價(jià)值
  }
};

匿名函數(shù)被分配給屬性 calculateWorth,但是真的需要 function 關(guān)鍵字嗎?在 ES6 中不需要!

let gemstone = {
  type,
  color,
  carat,
  calculateWorth() { ... }
};

for...of循環(huán)

for...of循環(huán)是最新添加到 JavaScript 循環(huán)系列中的循環(huán)。
它結(jié)合了其兄弟循環(huán)形式 for 循環(huán)和 for...in 循環(huán)的優(yōu)勢,可以循環(huán)任何可迭代(也就是遵守可迭代協(xié)議)類型的數(shù)據(jù)。默認(rèn)情況下,包含以下數(shù)據(jù)類型:String、Array、MapSet,注意不包含 Object 數(shù)據(jù)類型(即 {})。默認(rèn)情況下,對象不可迭代

for循環(huán)

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (let i = 0; i < digits.length; i++) {
  console.log(digits[i]);
}

for 循環(huán)的最大缺點(diǎn)是需要跟蹤計(jì)數(shù)器和退出條件。
雖然 for 循環(huán)在循環(huán)數(shù)組時的確具有優(yōu)勢,但是某些數(shù)據(jù)結(jié)構(gòu)不是數(shù)組,因此并非始終適合使用 loop 循環(huán)。

for...in循環(huán)

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (const index in digits) {
  console.log(digits[index]);
}

依然需要使用 index 來訪問數(shù)組的值

當(dāng)你需要向數(shù)組中添加額外的方法(或另一個對象)時,for...in 循環(huán)會帶來很大的麻煩。因?yàn)?for...in 循環(huán)循環(huán)訪問所有可枚舉的屬性,意味著如果向數(shù)組的原型中添加任何其他屬性,這些屬性也會出現(xiàn)在循環(huán)中。

Array.prototype.decimalfy = function() {
  for (let i = 0; i < this.length; i++) {
    this[i] = this[i].toFixed(2);
  }
};
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (const index in digits) {
  console.log(digits[index]);
}

forEach 循環(huán) 是另一種形式的 JavaScript 循環(huán)。但是,forEach() 實(shí)際上是數(shù)組方法,因此只能用在數(shù)組中。也無法停止或退出 forEach 循環(huán)。如果希望你的循環(huán)中出現(xiàn)這種行為,則需要使用基本的 for 循環(huán)。

for...of循環(huán)
for...of 循環(huán)用于循環(huán)訪問任何可迭代的數(shù)據(jù)類型。
for...of 循環(huán)的編寫方式和 for...in 循環(huán)的基本一樣,只是將 in 替換為 of,可以忽略索引。

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (const digit of digits) {
  console.log(digit);
}

建議使用復(fù)數(shù)對象名稱來表示多個值的集合。這樣,循環(huán)該集合時,可以使用名稱的單數(shù)版本來表示集合中的單個值。例如,for (const button of buttons) {…}。

for...of 循環(huán)還具有其他優(yōu)勢,解決了 for 和 for...in 循環(huán)的不足之處。你可以隨時停止或退出 for...of 循環(huán)。

for (const digit of digits) {
  if (digit % 2 === 0) {
    continue;
  }
  console.log(digit);
}

不用擔(dān)心向?qū)ο笾刑砑有碌膶傩浴?strong>for...of 循環(huán)將只循環(huán)訪問對象中的值。

Array.prototype.decimalfy = function() {
  for (i = 0; i < this.length; i++) {
    this[i] = this[i].toFixed(2);
  }
};
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (const digit of digits) {
  console.log(digit);
}

展開運(yùn)算符

展開運(yùn)算符(用三個連續(xù)的點(diǎn) (...) 表示)是 ES6 中的新概念,使你能夠?qū)⒆置媪繉ο笳归_為多個元素

const books = ["Don Quixote", "The Hobbit", "Alice in Wonderland", "Tale of Two Cities"];
console.log(...books);

Prints: Don Quixote The Hobbit Alice in Wonderland Tale of Two Cities

展開運(yùn)算符的一個用途是結(jié)合數(shù)組。

如果你需要結(jié)合多個數(shù)組,在有展開運(yùn)算符之前,必須使用 Arrayconcat() 方法。

const fruits = ["apples", "bananas", "pears"];
const vegetables = ["corn", "potatoes", "carrots"];
const produce = fruits.concat(vegetables);
console.log(produce);

Prints: ["apples", "bananas", "pears", "corn", "potatoes", "carrots"]

使用展開符來結(jié)合數(shù)組

const fruits = ["apples", "bananas", "pears"];
const vegetables = ["corn", "potatoes", "carrots"];
const produce = [...fruits,...vegetables];
console.log(produce);

剩余參數(shù)(可變參數(shù))

使用展開運(yùn)算符將數(shù)組展開為多個元素, 使用剩余參數(shù)可以將多個元素綁定到一個數(shù)組中.
剩余參數(shù)也用三個連續(xù)的點(diǎn) ( ... ) 表示,使你能夠?qū)⒉欢〝?shù)量的元素表示為數(shù)組.

用途1: 將變量賦數(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);

用途2: 可變參數(shù)函數(shù)
對于參數(shù)不固定的函數(shù),ES6之前是使用參數(shù)對象(arguments)處理:

function sum() {
  let total = 0;  
  for(const argument of arguments) {
    total += argument;
  }
  return total;
}

在ES6中使用剩余參數(shù)運(yùn)算符則更為簡潔,可讀性提高:

function sum(...nums) {
  let total = 0;  
  for(const num of nums) {
    total += num;
  }
  return total;
}

ES6箭頭函數(shù)

ES6之前,使用普通函數(shù)把其中每個名字轉(zhuǎn)換為大寫形式:

const upperizedNames = ['Farrin', 'Kagure', 'Asser'].map(function(name) { 
  return name.toUpperCase();
});

箭頭函數(shù)表示:

const upperizedNames = ['Farrin', 'Kagure', 'Asser'].map(
  name => name.toUpperCase()
);

普通函數(shù)可以是函數(shù)聲明或者函數(shù)表達(dá)式, 但是箭頭函數(shù)始終都是表達(dá)式, 全程是箭頭函數(shù)表達(dá)式, 因此因此僅在表達(dá)式有效時才能使用,包括:

  • 存儲在變量中,

  • 當(dāng)做參數(shù)傳遞給函數(shù),

  • 存儲在對象的屬性中。

const greet = name => `Hello ${name}!`;

可以如下調(diào)用:

greet('Asser');

如果函數(shù)的參數(shù)只有一個,不需要使用()包起來,但是只有一個或者多個, 則必須需要將參數(shù)列表放在圓括號內(nèi):

// 空參數(shù)列表需要括號
const sayHi = () => console.log('Hello Udacity Student!');
// 多個參數(shù)需要括號
const orderIceCream = (flavor, cone) => console.log(`Here's your ${flavor} ice cream in a ${cone} cone.`);
orderIceCream('chocolate', 'waffle');

一般箭頭函數(shù)都只有一個表達(dá)式作為函數(shù)主題:

const upperizedNames = ['Farrin', 'Kagure', 'Asser'].map(
  name => name.toUpperCase()
);

這種函數(shù)表達(dá)式形式稱為簡寫主體語法:

  • 在函數(shù)主體周圍沒有花括號,

  • 自動返回表達(dá)式

但是如果箭頭函數(shù)的主體內(nèi)需要多行代碼, 則需要使用常規(guī)主體語法:

  • 它將函數(shù)主體放在花括號內(nèi)

  • 需要使用 return 語句來返回內(nèi)容。

const upperizedNames = ['Farrin', 'Kagure', 'Asser'].map( name => {
  name = name.toUpperCase();
  return `${name} has ${name.length} characters in their name`;
});

javascript標(biāo)準(zhǔn)函數(shù)this

1、new 對象

const mySundae = new Sundae('Chocolate', ['Sprinkles', 'Hot Fudge']);

sundae這個構(gòu)造函數(shù)內(nèi)的this的值是實(shí)例對象, 因?yàn)樗褂胣ew被調(diào)用.

2、指定的對象

const result = obj1.printName.call(obj2);

函數(shù)使用call/apply被調(diào)用,this的值指向指定的obj2,因?yàn)?code>call()第一個參數(shù)明確設(shè)置this的指向

3、上下`文對象

data.teleport();

函數(shù)是對象的方法, this指向就是那個對象,此處this就是指向data.

4、全局對象或 undefined

teleport();

此處是this指向全局對象,在嚴(yán)格模式下,指向undefined.

javascript中this是很復(fù)雜的概念, 要詳細(xì)判斷this,請參考this豁然開朗

箭頭函數(shù)和this

對于普通函數(shù), this的值基于函數(shù)如何被調(diào)用, 對于箭頭函數(shù),this的值基于函數(shù)周圍的上下文, 換句話說,this的值和函數(shù)外面的this的值是一樣的.

function IceCream() {
    this.scoops = 0;
}
// 為 IceCream 添加 addScoop 方法
IceCream.prototype.addScoop = function() {
    setTimeout(function() {
        this.scoops++;
        console.log('scoop added!');
        console.log(this.scoops); // undefined+1=NaN
        console.log(dessert.scoops); //0
    }, 500);
};

標(biāo)題

const dessert = new IceCream();
dessert.addScoop();

傳遞給 setTimeout() 的函數(shù)被調(diào)用時沒用到 new、call()apply(),也沒用到上下文對象。意味著函數(shù)內(nèi)的 this 的值是全局對象,不是 dessert 對象。實(shí)際上發(fā)生的情況是,創(chuàng)建了新的 scoops 變量(默認(rèn)值為 undefined),然后遞增(undefined + 1 結(jié)果為 NaN);

解決此問題的方式之一是使用閉包(closure):

// 構(gòu)造函數(shù)
function IceCream() {
  this.scoops = 0;
}
// 為 IceCream 添加 addScoop 方法
IceCream.prototype.addScoop = function() {
  const cone = this; // 設(shè)置 `this` 給 `cone`變量
  setTimeout(function() {
    cone.scoops++; // 引用`cone`變量
    console.log('scoop added!'); 
    console.log(dessert.scoops);//1
  }, 0.5);
};
const dessert = new IceCream();
dessert.addScoop();

箭頭函數(shù)的作用正是如此, 將setTimeOut()的函數(shù)改為剪頭函數(shù):

// 構(gòu)造函數(shù)
function IceCream() {
  this.scoops = 0;
}
// 為 IceCream 添加 addScoop 方法
IceCream.prototype.addScoop = function() {
  setTimeout(() => { // 一個箭頭函數(shù)被傳遞給setTimeout
    this.scoops++;
    console.log('scoop added!');
    console.log(dessert.scoops);//1
  }, 0.5);
};
const dessert = new IceCream();
dessert.addScoop();

默認(rèn)參數(shù)函數(shù)

function greet(name, greeting) {
  name = (typeof name !== 'undefined') ?  name : 'Student';
  greeting = (typeof greeting !== 'undefined') ?  greeting : 'Welcome';
  return `${greeting} ${name}!`;
}
greet(); // Welcome Student!
greet('James'); // Welcome James!
greet('Richard', 'Howdy'); // Howdy Richard!

greet() 函數(shù)中混亂的前兩行的作用是什么?它們的作用是當(dāng)所需的參數(shù)未提供時,為函數(shù)提供默認(rèn)的值。但是看起來很麻煩, ES6引入一種新的方式創(chuàng)建默認(rèn)值, 他叫默認(rèn)函數(shù)參數(shù):

function greet(name = 'Student', greeting = 'Welcome') {
  return `${greeting} ${name}!`;
}
greet(); // Welcome Student!
greet('James'); // Welcome James!
greet('Richard', 'Howdy'); // Howdy Richard!

默認(rèn)值與解構(gòu)

1、默認(rèn)值與解構(gòu)數(shù)組

function createGrid([width = 5, height = 5]) {
  return `Generates a ${width} x ${height} grid`;
}

createGrid([]); // Generates a 5 x 5 grid
createGrid([2]); // Generates a 2 x 5 grid
createGrid([2, 3]); // Generates a 2 x 3 grid
createGrid([undefined, 3]); // Generates a 5 x 3 grid

createGrid() 函數(shù)預(yù)期傳入的是數(shù)組。它通過解構(gòu)將數(shù)組中的第一項(xiàng)設(shè)為 width,第二項(xiàng)設(shè)為 height。如果數(shù)組為空,或者只有一項(xiàng),那么就會使用默認(rèn)參數(shù),并將缺失的參數(shù)設(shè)為默認(rèn)值 5。

但是存在一個問題:

createGrid(); // throws an error

Uncaught TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined

出現(xiàn)錯誤,因?yàn)?createGrid() 預(yù)期傳入的是數(shù)組,然后對其進(jìn)行解構(gòu)。因?yàn)楹瘮?shù)被調(diào)用時沒有傳入數(shù)組,所以出現(xiàn)問題。但是,我們可以使用默認(rèn)的函數(shù)參數(shù)!

function createGrid([width = 5, height = 5] = []) {
  return `Generating a grid of ${width} by ${height}`;
}
createGrid(); // Generates a 5 x 5 grid

Returns: Generates a 5 x 5 grid

2、默認(rèn)值與解構(gòu)函數(shù)

就像使用數(shù)組默認(rèn)值解構(gòu)數(shù)組一樣,函數(shù)可以讓對象成為一個默認(rèn)參數(shù),并使用對象解構(gòu):

function createSundae({scoops = 1, toppings = ['Hot Fudge']}={}) {
  const scoopText = scoops === 1 ? 'scoop' : 'scoops';
  return `Your sundae has ${scoops} ${scoopText} with ${toppings.join(' and ')} toppings.`;
}
createSundae({}); // Your sundae has 1 scoop with Hot Fudge toppings.
createSundae({scoops: 2}); // Your sundae has 2 scoops with Hot Fudge toppings.
createSundae({scoops: 2, toppings: ['Sprinkles']}); // Your sundae has 2 scoops with Sprinkles toppings.
createSundae({toppings: ['Cookie Dough']}); // Your sundae has 1 scoop with Cookie Dough toppings.
createSundae(); // Your sundae has 1 scoop with Hot Fudge toppings.

3、數(shù)組默認(rèn)值與對象默認(rèn)值

默認(rèn)函數(shù)參數(shù)只是個簡單的添加內(nèi)容,但是卻帶來很多便利!與數(shù)組默認(rèn)值相比,對象默認(rèn)值具備的一個優(yōu)勢是能夠處理跳過的選項(xiàng)??纯聪旅娴拇a:

function createSundae({scoops = 1, toppings = ['Hot Fudge']} = {}) { … }

createSundae() 函數(shù)使用對象默認(rèn)值進(jìn)行解構(gòu)時,如果你想使用 scoops 的默認(rèn)值,但是更改 toppings,那么只需使用 toppings 傳入一個對象:

createSundae({toppings: ['Hot Fudge', 'Sprinkles', 'Caramel']});

將上述示例與使用數(shù)組默認(rèn)值進(jìn)行解構(gòu)的同一函數(shù)相對比。

function createSundae([scoops = 1, toppings = ['Hot Fudge']] = []) { … }

對于這個函數(shù),如果想使用 scoops 的默認(rèn)數(shù)量,但是更改 toppings,則必須以這種奇怪的方式調(diào)用你的函數(shù):

createSundae([undefined, ['Hot Fudge', 'Sprinkles', 'Caramel']]);

因?yàn)閿?shù)組是基于位置的,我們需要傳入 undefined 以跳過第一個參數(shù)(并使用默認(rèn)值)來到達(dá)第二個參數(shù)。

Javascript類

ES5創(chuàng)建類:

function Plane(numEngines) {
  this.numEngines = numEngines;
  this.enginesActive = false;
}
// 由所有實(shí)例 "繼承" 的方法
Plane.prototype.startEngines = function () {
  console.log('starting engines...');
  this.enginesActive = true;
};

ES6類只是一個語法糖,原型繼續(xù)實(shí)際上在底層隱藏起來, 與傳統(tǒng)類機(jī)制語言有些區(qū)別.

class Plane {
  //constructor方法雖然在類中,但不是原型上的方法,只是用來生成實(shí)例的.
  constructor(numEngines) {
    this.numEngines = numEngines;
    this.enginesActive = false;
  }
  //原型上的方法, 由所有實(shí)例對象共享.
  startEngines() {
    console.log('starting engines…');
    this.enginesActive = true;
  }
}
console.log(typeof Plane); //function

javascript中類其實(shí)只是function, 方法之間不能使用,,不用逗號區(qū)分屬性和方法.

靜態(tài)方法

要添加靜態(tài)方法,請?jiān)诜椒Q前面加上關(guān)鍵字 static

class Plane {
  constructor(numEngines) {
    this.numEngines = numEngines;
    this.enginesActive = false;
  }
  static badWeather(planes) {
    for (plane of planes) {
      plane.enginesActive = false;
    }
  }
  startEngines() {
    console.log('starting engines…');
    this.enginesActive = true;
  }
}
  • 關(guān)鍵字class帶來其他基于類的語言的很多思想,但是沒有向javascript中添加此功能

  • javascript類實(shí)際上還是原型繼承

  • 創(chuàng)建javascript類的新實(shí)例時必須使用new關(guān)鍵字

super 和 extends

使用新的super和extends關(guān)鍵字?jǐn)U展類:

class Tree {
  constructor(size = '10', leaves = {spring: 'green', summer: 'green', fall: 'orange', winter: null}) {
    this.size = size;
    this.leaves = leaves;
    this.leafColor = null;
  }
  changeSeason(season) {
    this.leafColor = this.leaves[season];
    if (season === 'spring') {
      this.size += 1;
    }
  }
}
class Maple extends Tree {
  constructor(syrupQty = 15, size, leaves) {
    super(size, leaves); //super用作函數(shù)
    this.syrupQty = syrupQty;
  }
  changeSeason(season) {
    super.changeSeason(season);//super用作對象
    if (season === 'spring') {
      this.syrupQty += 1;
    }
  }
  gatherSyrup() {
    this.syrupQty -= 3;
  }
}

使用ES5編寫同樣功能的類:

function Tree(size, leaves) {
  this.size = size || 10;
  this.leaves = leaves || {spring: 'green', summer: 'green', fall: 'orange', winter: null};
  this.leafColor;
}
Tree.prototype.changeSeason = function(season) {
  this.leafColor = this.leaves[season];
  if (season === 'spring') {
    this.size += 1;
  }
}
function Maple (syrupQty, size, leaves) {
  Tree.call(this, size, leaves);
  this.syrupQty = syrupQty || 15;
}
Maple.prototype = Object.create(Tree.prototype);
Maple.prototype.constructor = Maple;
Maple.prototype.changeSeason = function(season) {
  Tree.prototype.changeSeason.call(this, season);
  if (season === 'spring') {
    this.syrupQty += 1;
  }
}
Maple.prototype.gatherSyrup = function() {
  this.syrupQty -= 3;
}

super 必須在 this 之前被調(diào)用

在子類構(gòu)造函數(shù)中,在使用 this 之前,必須先調(diào)用超級類。

class Apple {}
class GrannySmith extends Apple {
  constructor(tartnessLevel, energy) {
    this.tartnessLevel = tartnessLevel; // 在 'super' 之前會拋出一個錯誤!
    super(energy); 
  }
}

字符串模板

字符串模板相對簡單易懂些。ES6中允許使用反引號 ` 來創(chuàng)建字符串,此種方法創(chuàng)建的字符串里面可以包含由美元符號加花括號包裹的變量${vraible}。如果你使用過像C#等后端強(qiáng)類型語言的話,對此功能應(yīng)該不會陌生。

//產(chǎn)生一個隨機(jī)數(shù)
var num=Math.random();
//將這個數(shù)字輸出到console
console.log(`your num is ${num}`);

iterator, generator

這一部分的內(nèi)容有點(diǎn)生澀,詳情可以參見這里。以下是些基本概念。

  • iterator:它是這么一個對象,擁有一個next方法,這個方法返回一個對象{done,value},這個對象包含兩個屬性,一個布爾類型的done和包含任意值的value

  • iterable: 這是這么一個對象,擁有一個obj[@@iterator]方法,這個方法返回一個iterator

  • generator: 它是一種特殊的iterator。反的next方法可以接收一個參數(shù)并且返回值取決與它的構(gòu)造函數(shù)(generator function)。generator同時擁有一個throw方法

  • generator 函數(shù): 即generator的構(gòu)造函數(shù)。此函數(shù)內(nèi)可以使用yield關(guān)鍵字。在yield出現(xiàn)的地方可以通過generator的next或throw方法向外界傳遞值。generator 函數(shù)是通過function*來聲明的

  • yield 關(guān)鍵字:它可以暫停函數(shù)的執(zhí)行,隨后可以再進(jìn)進(jìn)入函數(shù)繼續(xù)執(zhí)行

模塊

在ES6標(biāo)準(zhǔn)中,JavaScript原生支持module了。這種將JS代碼分割成不同功能的小塊進(jìn)行模塊化的概念是在一些三方規(guī)范中流行起來的,比如CommonJS和AMD模式。

將不同功能的代碼分別寫在不同文件中,各模塊只需導(dǎo)出公共接口部分,然后通過模塊的導(dǎo)入的方式可以在其他地方使用。下面的例子來自tutsplus:

// point.js
module "point" {
    export class Point {
        constructor (x, y) {
            public x = x;
            public y = y;
        }
    }
}
 
// myapp.js
//聲明引用的模塊
module point from "/point.js";
//這里可以看出,盡管聲明了引用的模塊,還是可以通過指定需要的部分進(jìn)行導(dǎo)入
import Point from "point";
 
var origin = new Point(0, 0);
console.log(origin);

Map,Set 和 WeakMap,WeakSet

這些是新加的集合類型,提供了更加方便的獲取屬性值的方法,不用像以前一樣用hasOwnProperty來檢查某個屬性是屬于原型鏈上的呢還是當(dāng)前對象的。同時,在進(jìn)行屬性值添加與獲取時有專門的get,set 方法。

下方代碼來自es6feature

// Sets
var s = new Set();
s.add("hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") === true;

// Maps
var m = new Map();
m.set("hello", 42);
m.set(s, 34);
m.get(s) == 34;

有時候我們會把對象作為一個對象的鍵用來存放屬性值,普通集合類型比如簡單對象會阻止垃圾回收器對這些作為屬性鍵存在的對象的回收,有造成內(nèi)存泄漏的危險(xiǎn)。而WeakMap,WeakSet則更加安全些,這些作為屬性鍵的對象如果沒有別的變量在引用它們,則會被回收釋放掉,具體還看下面的例子。

正文代碼來自es6feature

// Weak Maps
var wm = new WeakMap();
wm.set(s, { extra: 42 });
wm.size === undefined

// Weak Sets
var ws = new WeakSet();
ws.add({ data: 42 });//因?yàn)樘砑拥絯s的這個臨時對象沒有其他變量引用它,所以ws不會保存它的值,也就是說這次添加其實(shí)沒有意思

Proxies

Proxy可以監(jiān)聽對象身上發(fā)生了什么事情,并在這些事情發(fā)生后執(zhí)行一些相應(yīng)的操作。一下子讓我們對一個對象有了很強(qiáng)的追蹤能力,同時在數(shù)據(jù)綁定方面也很有用處。

以下例子借用自這里。

//定義被偵聽的目標(biāo)對象
var engineer = { name: 'Joe Sixpack', salary: 50 };
//定義處理程序
var interceptor = {
  set: function (receiver, property, value) {
    console.log(property, 'is changed to', value);
    receiver[property] = value;
  }
};
//創(chuàng)建代理以進(jìn)行偵聽
engineer = Proxy(engineer, interceptor);
//做一些改動來觸發(fā)代理
engineer.salary = 60;//控制臺輸出:salary is changed to 60

上面代碼我已加了注釋,這里進(jìn)一步解釋。對于處理程序,是在被偵聽的對象身上發(fā)生了相應(yīng)事件之后,處理程序里面的方法就會被調(diào)用,上面例子中我們設(shè)置了set的處理函數(shù),表明,如果我們偵聽的對象的屬性被更改,也就是被set了,那這個處理程序就會被調(diào)用,同時通過參數(shù)能夠得知是哪個屬性被更改,更改為了什么值。

Symbols

我們知道對象其實(shí)是鍵值對的集合,而鍵通常來說是字符串。而現(xiàn)在除了字符串外,我們還可以用symbol這種值來做為對象的鍵。Symbol是一種基本類型,像數(shù)字,字符串還有布爾一樣,它不是一個對象。Symbol 通過調(diào)用symbol函數(shù)產(chǎn)生,它接收一個可選的名字參數(shù),該函數(shù)返回的symbol是唯一的。之后就可以用這個返回值做為對象的鍵了。Symbol還可以用來創(chuàng)建私有屬性,外部無法直接訪問由symbol做為鍵的屬性值。

以下例子來自es6features

(function() {

  // 創(chuàng)建symbol
  var key = Symbol("key");

  function MyClass(privateData) {
    this[key] = privateData;
  }

  MyClass.prototype = {
    doStuff: function() {
      ... this[key] ...
    }
  };

})();

var c = new MyClass("hello")
c["key"] === undefined//無法訪問該屬性,因?yàn)槭撬接械?/pre>

Math,Number,String,Object 的新API

對Math,Number,String還有Object等添加了許多新的API。下面代碼同樣來自es6features,對這些新API進(jìn)行了簡單展示。

Number.EPSILON
Number.isInteger(Infinity) // false
Number.isNaN("NaN") // false

Math.acosh(3) // 1.762747174039086
Math.hypot(3, 4) // 5
Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // 2

"abcde".contains("cd") // true
"abc".repeat(3) // "abcabcabc"

Array.from(document.querySelectorAll('*')) // Returns a real Array
Array.of(1, 2, 3) // Similar to new Array(...), but without special one-arg behavior
[0, 0, 0].fill(7, 1) // [0,7,7]
[1,2,3].findIndex(x => x == 2) // 1
["a", "b", "c"].entries() // iterator [0, "a"], [1,"b"], [2,"c"]
["a", "b", "c"].keys() // iterator 0, 1, 2
["a", "b", "c"].values() // iterator "a", "b", "c"

Object.assign(Point, { origin: new Point(0,0) })

Promises

Promises是處理異步操作的一種模式,之前在很多三方庫中有實(shí)現(xiàn),比如jQuery的deferred 對象。當(dāng)你發(fā)起一個異步請求,并綁定了.when(), .done()等事件處理程序時,其實(shí)就是在應(yīng)用promise模式。

//創(chuàng)建promise
var promise = new Promise(function(resolve, reject) {
    // 進(jìn)行一些異步或耗時操作
    if ( /*如果成功 */ ) {
        resolve("Stuff worked!");
    } else {
        reject(Error("It broke"));
    }
});
//綁定處理程序
promise.then(function(result) {
	//promise成功的話會執(zhí)行這里
    console.log(result); // "Stuff worked!"
}, function(err) {
	//promise失敗會執(zhí)行這里
    console.log(err); // Error: "It broke"
});

關(guān)于“es6的新特性是什么”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

es6
AI