ES6、ES7、ES8學(xué)習(xí)指南

期待已久的新課上線啦!解鎖React Native開發(fā)新姿勢,一網(wǎng)打盡React Native最新與最熱技術(shù),點我Get!!!

概述

ES全稱ECMAScript,ECMAScript是ECMA制定的標(biāo)準(zhǔn)化腳本語言。目前JavaScript使用的ECMAScript版本為ECMAScript-262。

ECMAScript 標(biāo)準(zhǔn)建立在一些原有的技術(shù)上,最為著名的是 JavaScript (網(wǎng)景) 和 JScript (微軟)。它最初由網(wǎng)景的 Brendan Eich 發(fā)明,第一次出現(xiàn)是在網(wǎng)景的 Navigator 2.0 瀏覽器上。Netscape 2.0 以及微軟 Internet Explorer 3.0 后序的所有瀏覽器上都有它的身影。

ECMAScript版本 發(fā)布時間 新增特性
ECMAScript 2009(ES5) 2009年11月 擴展了Object、Array、Function的功能等
ECMAScript 2015(ES6) 2015年6月 類,模塊化,箭頭函數(shù),函數(shù)參數(shù)默認(rèn)值等
ECMAScript 2016(ES7) 2016年3月 includes,指數(shù)操作符
ECMAScript 2017(ES8) 2017年6月 sync/await,Object.values(),Object.entries(),String padding等

了解這些特性,不僅能使我們的編碼更加的符合規(guī)范,而且能提高我們Coding的效率。

ES6的特性

ES6的特性比較多,在 ES5 發(fā)布近 6 年(2009-11 至 2015-6)之后才將其標(biāo)準(zhǔn)化。兩個發(fā)布版本之間時間跨度很大,所以ES6中的特性比較多。

在這里列舉幾個常用的:

  • 模塊化
  • 箭頭函數(shù)
  • 函數(shù)參數(shù)默認(rèn)值
  • 模板字符串
  • 解構(gòu)賦值
  • 延展操作符
  • 對象屬性簡寫
  • Promise
  • Let與Const

1.類(class)

對熟悉Java,object-c,c#等純面向?qū)ο笳Z言的開發(fā)者來說,都會對class有一種特殊的情懷。ES6 引入了class(類),讓JavaScript的面向?qū)ο缶幊套兊酶雍唵魏鸵子诶斫狻?/p>

  class Animal {
    // 構(gòu)造函數(shù),實例化的時候?qū)徽{(diào)用,如果不指定,那么會有一個不帶參數(shù)的默認(rèn)構(gòu)造函數(shù).
    constructor(name,color) {
      this.name = name;
      this.color = color;
    }
    // toString 是原型對象上的屬性
    toString() {
      console.log('name:' + this.name + ',color:' + this.color);

    }
  }

 var animal = new Animal('dog','white');//實例化Animal
 animal.toString();

 console.log(animal.hasOwnProperty('name')); //true
 console.log(animal.hasOwnProperty('toString')); // false
 console.log(animal.__proto__.hasOwnProperty('toString')); // true

 class Cat extends Animal {
  constructor(action) {
    // 子類必須要在constructor中指定super 函數(shù),否則在新建實例的時候會報錯.
    // 如果沒有置頂consructor,默認(rèn)帶super函數(shù)的constructor將會被添加、
    super('cat','white');
    this.action = action;
  }
  toString() {
    console.log(super.toString());
  }
 }

 var cat = new Cat('catch')
 cat.toString();

 // 實例cat 是 Cat 和 Animal 的實例,和Es5完全一致。
 console.log(cat instanceof Cat); // true
 console.log(cat instanceof Animal); // true

2.模塊化(Module)

ES5不支持原生的模塊化,在ES6中模塊作為重要的組成部分被添加進來。模塊的功能主要由 export 和 import 組成。每一個模塊都有自己單獨的作用域,模塊之間的相互調(diào)用關(guān)系是通過 export 來規(guī)定模塊對外暴露的接口,通過import來引用其它模塊提供的接口。同時還為模塊創(chuàng)造了命名空間,防止函數(shù)的命名沖突。

導(dǎo)出(export)

ES6允許在一個模塊中使用export來導(dǎo)出多個變量或函數(shù)。

導(dǎo)出變量

//test.js
export var name = 'Rainbow'

心得:ES6不僅支持變量的導(dǎo)出,也支持常量的導(dǎo)出。 export const sqrt = Math.sqrt;//導(dǎo)出常量

ES6將一個文件視為一個模塊,上面的模塊通過 export 向外輸出了一個變量。一個模塊也可以同時往外面輸出多個變量。

 //test.js
 var name = 'Rainbow';
 var age = '24';
 export {name, age};

導(dǎo)出函數(shù)

// myModule.js
export function myModule(someArg) {
  return someArg;
}  

導(dǎo)入(import)

定義好模塊的輸出以后就可以在另外一個模塊通過import引用。

import {myModule} from 'myModule';// main.js
import {name,age} from 'test';// test.js

心得:一條import 語句可以同時導(dǎo)入默認(rèn)函數(shù)和其它變量。import defaultMethod, { otherMethod } from 'xxx.js';

3.箭頭(Arrow)函數(shù)

這是ES6中最令人激動的特性之一。=>不只是關(guān)鍵字function的簡寫,它還帶來了其它好處。箭頭函數(shù)與包圍它的代碼共享同一個this,能幫你很好的解決this的指向問題。有經(jīng)驗的JavaScript開發(fā)者都熟悉諸如var self = this;var that = this這種引用外圍this的模式。但借助=>,就不需要這種模式了。

箭頭函數(shù)的結(jié)構(gòu)

箭頭函數(shù)的箭頭=>之前是一個空括號、單個的參數(shù)名、或用括號括起的多個參數(shù)名,而箭頭之后可以是一個表達式(作為函數(shù)的返回值),或者是用花括號括起的函數(shù)體(需要自行通過return來返回值,否則返回的是undefined)。

// 箭頭函數(shù)的例子
()=>1
v=>v+1
(a,b)=>a+b
()=>{
    alert("foo");
}
e=>{
    if (e == 0){
        return 0;
    }
    return 1000/e;
}

心得:不論是箭頭函數(shù)還是bind,每次被執(zhí)行都返回的是一個新的函數(shù)引用,因此如果你還需要函數(shù)的引用去做一些別的事情(譬如卸載監(jiān)聽器),那么你必須自己保存這個引用。

卸載監(jiān)聽器時的陷阱

錯誤的做法

class PauseMenu extends React.Component{
    componentWillMount(){
        AppStateIOS.addEventListener('change', this.onAppPaused.bind(this));
    }
    componentWillUnmount(){
        AppStateIOS.removeEventListener('change', this.onAppPaused.bind(this));
    }
    onAppPaused(event){
    }
}

正確的做法

class PauseMenu extends React.Component{
    constructor(props){
        super(props);
        this._onAppPaused = this.onAppPaused.bind(this);
    }
    componentWillMount(){
        AppStateIOS.addEventListener('change', this._onAppPaused);
    }
    componentWillUnmount(){
        AppStateIOS.removeEventListener('change', this._onAppPaused);
    }
    onAppPaused(event){
    }
}

除上述的做法外,我們還可以這樣做:

class PauseMenu extends React.Component{
    componentWillMount(){
        AppStateIOS.addEventListener('change', this.onAppPaused);
    }
    componentWillUnmount(){
        AppStateIOS.removeEventListener('change', this.onAppPaused);
    }
    onAppPaused = (event) => {
        //把函數(shù)直接作為一個arrow function的屬性來定義,初始化的時候就綁定好了this指針
    }
}

需要注意的是:不論是bind還是箭頭函數(shù),每次被執(zhí)行都返回的是一個新的函數(shù)引用,因此如果你還需要函數(shù)的引用去做一些別的事情(譬如卸載監(jiān)聽器),那么你必須自己保存這個引用。

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

ES6支持在定義函數(shù)的時候為其設(shè)置默認(rèn)值:

function foo(height = 50, color = 'red')
{
    // ...
}

不使用默認(rèn)值:

function foo(height, color)
{
    var height = height || 50;
    var color = color || 'red';
    //...
}

這樣寫一般沒問題,但當(dāng)參數(shù)的布爾值為false時,就會有問題了。比如,我們這樣調(diào)用foo函數(shù):

foo(0, "")

因為0的布爾值為false,這樣height的取值將是50。同理color的取值為‘red’。

所以說,函數(shù)參數(shù)默認(rèn)值不僅能是代碼變得更加簡潔而且能規(guī)避一些問題。

5.模板字符串

ES6支持模板字符串,使得字符串的拼接更加的簡潔、直觀。

不使用模板字符串:

var name = 'Your name is ' + first + ' ' + last + '.'

使用模板字符串:

var name = `Your name is ${first} ${last}.`

在ES6中通過${}就可以完成字符串的拼接,只需要將變量放在大括號之中。

6.解構(gòu)賦值

解構(gòu)賦值語法是JavaScript的一種表達式,可以方便的從數(shù)組或者對象中快速提取值賦給定義的變量。

獲取數(shù)組中的值

從數(shù)組中獲取值并賦值到變量中,變量的順序與數(shù)組中對象順序?qū)?yīng)。

var foo = ["one", "two", "three", "four"];

var [one, two, three] = foo;
console.log(one); // "one"
console.log(two); // "two"
console.log(three); // "three"

//如果你要忽略某些值,你可以按照下面的寫法獲取你想要的值
var [first, , , last] = foo;
console.log(first); // "one"
console.log(last); // "four"

//你也可以這樣寫
var a, b; //先聲明變量

[a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2

如果沒有從數(shù)組中的獲取到值,你可以為變量設(shè)置一個默認(rèn)值。

var a, b;

[a=5, b=7] = [1];
console.log(a); // 1
console.log(b); // 7

通過解構(gòu)賦值可以方便的交換兩個變量的值。

var a = 1;
var b = 3;

[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1

獲取對象中的值

const student = {
  name:'Ming',
  age:'18',
  city:'Shanghai'  
};

const {name,age,city} = student;
console.log(name); // "Ming"
console.log(age); // "18"
console.log(city); // "Shanghai"

7.延展操作符(Spread operator)

延展操作符...可以在函數(shù)調(diào)用/數(shù)組構(gòu)造時, 將數(shù)組表達式或者string在語法層面展開;還可以在構(gòu)造對象時, 將對象表達式按key-value的方式展開。

語法

函數(shù)調(diào)用:

myFunction(...iterableObj);

數(shù)組構(gòu)造或字符串:

[...iterableObj, '4', ...'hello', 6];

構(gòu)造對象時,進行克隆或者屬性拷貝(ECMAScript 2018規(guī)范新增特性):

let objClone = { ...obj };

應(yīng)用場景

在函數(shù)調(diào)用時使用延展操作符

function sum(x, y, z) {
  return x + y + z;
}
const numbers = [1, 2, 3];

//不使用延展操作符
console.log(sum.apply(null, numbers));

//使用延展操作符
console.log(sum(...numbers));// 6

構(gòu)造數(shù)組

沒有展開語法的時候,只能組合使用 push,splice,concat 等方法,來將已有數(shù)組元素變成新數(shù)組的一部分。有了展開語法, 構(gòu)造新數(shù)組會變得更簡單、更優(yōu)雅:

const stuendts = ['Jine','Tom']; 
const persons = ['Tony',... stuendts,'Aaron','Anna'];
conslog.log(persions)// ["Tony", "Jine", "Tom", "Aaron", "Anna"]

和參數(shù)列表的展開類似, ... 在構(gòu)造字?jǐn)?shù)組時, 可以在任意位置多次使用。

數(shù)組拷貝

var arr = [1, 2, 3];
var arr2 = [...arr]; // 等同于 arr.slice()
arr2.push(4); 
console.log(arr2)//[1, 2, 3, 4]

展開語法和 Object.assign() 行為一致, 執(zhí)行的都是淺拷貝(只遍歷一層)。

連接多個數(shù)組

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
var arr3 = [...arr1, ...arr2];// 將 arr2 中所有元素附加到 arr1 后面并返回
//等同于
var arr4 = arr1.concat(arr2);

在ECMAScript 2018中延展操作符增加了對對象的支持

var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };

var clonedObj = { ...obj1 };
// 克隆后的對象: { foo: "bar", x: 42 }

var mergedObj = { ...obj1, ...obj2 };
// 合并后的對象: { foo: "baz", x: 42, y: 13 }

在React中的應(yīng)用

通常我們在封裝一個組件時,會對外公開一些 props 用于實現(xiàn)功能。大部分情況下在外部使用都應(yīng)顯示的傳遞 props 。但是當(dāng)傳遞大量的props時,會非常繁瑣,這時我們可以使用 ...(延展操作符,用于取出參數(shù)對象的所有可遍歷屬性) 來進行傳遞。

一般情況下我們應(yīng)該這樣寫

<CustomComponent name ='Jine' age ={21} />

使用 ... ,等同于上面的寫法

const params = {
        name: 'Jine',
        age: 21
    }

<CustomComponent {...params} />

配合解構(gòu)賦值避免傳入一些不需要的參數(shù)

var params = {
    name: '123',
    title: '456',
    type: 'aaa'
}

var { type, ...other } = params;

<CustomComponent type='normal' number={2} {...other} />
//等同于
<CustomComponent type='normal' number={2} name='123' title='456' />

8.對象屬性簡寫

在ES6中允許我們在設(shè)置一個對象的屬性的時候不指定屬性名。

不使用ES6

const name='Ming',age='18',city='Shanghai';
        
const student = {
    name:name,
    age:age,
    city:city
};
console.log(student);//{name: "Ming", age: "18", city: "Shanghai"}

對象中必須包含屬性和值,顯得非常冗余。

使用ES6

const name='Ming',age='18',city='Shanghai';
        
const student = {
    name,
    age,
    city
};
console.log(student);//{name: "Ming", age: "18", city: "Shanghai"}

對象中直接寫變量,非常簡潔。

9.Promise

Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案callback更加的優(yōu)雅。它最早由社區(qū)提出和實現(xiàn)的,ES6 將其寫進了語言標(biāo)準(zhǔn),統(tǒng)一了用法,原生提供了Promise對象。

不使用ES6

嵌套兩個setTimeout回調(diào)函數(shù):

setTimeout(function()
{
    console.log('Hello'); // 1秒后輸出"Hello"
    setTimeout(function()
    {
        console.log('Hi'); // 2秒后輸出"Hi"
    }, 1000);
}, 1000);

使用ES6

var waitSecond = new Promise(function(resolve, reject)
{
    setTimeout(resolve, 1000);
});

waitSecond
    .then(function()
    {
        console.log("Hello"); // 1秒后輸出"Hello"
        return waitSecond;
    })
    .then(function()
    {
        console.log("Hi"); // 2秒后輸出"Hi"
    });

上面的的代碼使用兩個then來進行異步編程串行化,避免了回調(diào)地獄:

10.支持let與const

在之前JS是沒有塊級作用域的,const與let填補了這方便的空白,const與let都是塊級作用域。

使用var定義的變量為函數(shù)級作用域:

{
  var a = 10;
}

console.log(a); // 輸出10

使用let與const定義的變量為塊級作用域:

{
  let a = 10;
}

console.log(a); //-1 or Error“ReferenceError: a is not defined”

ES7的特性

在ES6之后,ES的發(fā)布頻率更加頻繁,基本每年一次,所以自ES6之后,每個新版本的特性的數(shù)量就比較少。

  • includes()
  • 指數(shù)操作符

1. Array.prototype.includes()

includes() 函數(shù)用來判斷一個數(shù)組是否包含一個指定的值,如果包含則返回 true,否則返回false。

includes 函數(shù)與 indexOf 函數(shù)很相似,下面兩個表達式是等價的:

arr.includes(x)
arr.indexOf(x) >= 0

接下來我們來判斷數(shù)字中是否包含某個元素:

在ES7之前的做法

使用indexOf()驗證數(shù)組中是否存在某個元素,這時需要根據(jù)返回值是否為-1來判斷:

let arr = ['react', 'angular', 'vue'];

if (arr.indexOf('react') !== -1)
{
    console.log('react存在');
}

使用ES7的includes()

使用includes()驗證數(shù)組中是否存在某個元素,這樣更加直觀簡單:

let arr = ['react', 'angular', 'vue'];

if (arr.includes('react'))
{
    console.log('react存在');
}

2.指數(shù)操作符

在ES7中引入了指數(shù)運算符**,**具有與Math.pow(..)等效的計算結(jié)果。

不使用指數(shù)操作符

使用自定義的遞歸函數(shù)calculateExponent或者Math.pow()進行指數(shù)運算:

function calculateExponent(base, exponent)
{
    if (exponent === 1)
    {
        return base;
    }
    else
    {
        return base * calculateExponent(base, exponent - 1);
    }
}

console.log(calculateExponent(2, 10)); // 輸出1024
console.log(Math.pow(2, 10)); // 輸出1024

使用指數(shù)操作符

使用指數(shù)運算符**,就像+、-等操作符一樣:

console.log(2**10);// 輸出1024

ES8的特性

  • async/await
  • Object.values()
  • Object.entries()
  • String padding
  • 函數(shù)參數(shù)列表結(jié)尾允許逗號
  • Object.getOwnPropertyDescriptors()

瀏覽器兼容性

1.async/await

在ES8中加入了對async/await的支持,也就我們所說的異步函數(shù),這是一個很實用的功能。 async/await將我們從頭痛的回調(diào)地獄中解脫出來了,使整個代碼看起來很簡潔。

使用async/await與不使用async/await的差別:

login(userName) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('1001');
        }, 600);
    });
}

getData(userId) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (userId === '1001') {
                resolve('Success');
            } else {
                reject('Fail');
            }
        }, 600);
    });
}

// 不使用async/await ES7
doLogin(userName) {
    this.login(userName)
        .then(this.getData)
        .then(result => {
            console.log(result)
        })
}

// 使用async/await ES8
async doLogin2(userName) {
    const userId=await this.login(userName);
    const result=await this.getData(userId);
}

this.doLogin()// Success
this.doLogin2()// Success

async/await的幾種應(yīng)用場景

接下來我們來看一下async/await的幾種應(yīng)用場景。

獲取異步函數(shù)的返回值

異步函數(shù)本身會返回一個Promise,所以我們可以通過then來獲取異步函數(shù)的返回值。

async function charCountAdd(data1, data2) {
    const d1=await charCount(data1);
    const d2=await charCount(data2);
    return d1+d2;
}
charCountAdd('Hello','Hi').then(console.log);//通過then獲取異步函數(shù)的返回值。
function charCount(data) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(data.length);
        }, 1000);
    });
}

async/await在并發(fā)場景中的應(yīng)用

對于上述的例子,我們調(diào)用await兩次,每次都是等待1秒一共是2秒,效率比較低,而且兩次await的調(diào)用并沒有依賴關(guān)系,那能不能讓其并發(fā)執(zhí)行呢,答案是可以的,接下來我們通過Promise.all來實現(xiàn)await的并發(fā)調(diào)用。

async function charCountAdd(data1, data2) {
    const [d1,d2]=await Promise.all([charCount(data1),charCount(data2)]);
    return d1+d2;
}
charCountAdd('Hello','Hi').then(console.log);
function charCount(data) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(data.length);
        }, 1000);
    });
}

通過上述代碼我們實現(xiàn)了兩次charCount的并發(fā)調(diào)用,Promise.all接受的是一個數(shù)組,它可以將數(shù)組中的promise對象并發(fā)執(zhí)行;

async/await的幾種錯誤處理方式

第一種:捕捉整個async/await函數(shù)的錯誤

async function charCountAdd(data1, data2) {
    const d1=await charCount(data1);
    const d2=await charCount(data2);
    return d1+d2;
}
charCountAdd('Hello','Hi')
    .then(console.log)
    .catch(console.log);//捕捉整個async/await函數(shù)的錯誤
...

這種方式可以捕捉整個charCountAdd運行過程中出現(xiàn)的錯誤,錯誤可能是由charCountAdd本身產(chǎn)生的,也可能是由對data1的計算中或data2的計算中產(chǎn)生的。

第二種:捕捉單個的await表達式的錯誤

async function charCountAdd(data1, data2) {
    const d1=await charCount(data1)
        .catch(e=>console.log('d1 is null'));
    const d2=await charCount(data2)
        .catch(e=>console.log('d2 is null'));
    return d1+d2;
}
charCountAdd('Hello','Hi').then(console.log);

通過這種方式可以捕捉每一個await表達式的錯誤,如果既要捕捉每一個await表達式的錯誤,又要捕捉整個charCountAdd函數(shù)的錯誤,可以在調(diào)用charCountAdd的時候加個catch。

...
charCountAdd('Hello','Hi')
    .then(console.log)
    .catch(console.log);//捕捉整個async/await函數(shù)的錯誤
...

第三種:同時捕捉多個的await表達式的錯誤

async function charCountAdd(data1, data2) {
    let d1,d2;
    try {
        d1=await charCount(data1);
        d2=await charCount(data2);
    }catch (e){
        console.log('d1 is null');
    }
    return d1+d2;
}
charCountAdd('Hello','Hi')
    .then(console.log);

function charCount(data) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(data.length);
        }, 1000);
    });
}

2.Object.values()

Object.values()是一個與Object.keys()類似的新函數(shù),但返回的是Object自身屬性的所有值,不包括繼承的值。

假設(shè)我們要遍歷如下對象obj的所有值:

const obj = {a: 1, b: 2, c: 3};

不使用Object.values() :ES7

const vals=Object.keys(obj).map(key=>obj[key]);
console.log(vals);//[1, 2, 3]

使用Object.values() :ES8

const values=Object.values(obj1);
console.log(values);//[1, 2, 3]

從上述代碼中可以看出Object.values()為我們省去了遍歷key,并根據(jù)這些key獲取value的步驟。

3.Object.entries

Object.entries()函數(shù)返回一個給定對象自身可枚舉屬性的鍵值對的數(shù)組。

接下來我們來遍歷上文中的obj對象的所有屬性的key和value:

不使用Object.entries() :ES7

Object.keys(obj).forEach(key=>{
    console.log('key:'+key+' value:'+obj[key]);
})
//key:a value:1
//key:b value:2
//key:c value:3

使用Object.entries() :ES8

for(let [key,value] of Object.entries(obj1)){
    console.log(`key: ${key} value:${value}`)
}
//key:a value:1
//key:b value:2
//key:c value:3

4.String padding

在ES8中String新增了兩個實例函數(shù)String.prototype.padStartString.prototype.padEnd,允許將空字符串或其他字符串添加到原始字符串的開頭或結(jié)尾。

String.padStart(targetLength,[padString])

  • targetLength:當(dāng)前字符串需要填充到的目標(biāo)長度。如果這個數(shù)值小于當(dāng)前字符串的長度,則返回當(dāng)前字符串本身。
  • padString:(可選)填充字符串。如果字符串太長,使填充后的字符串長度超過了目標(biāo)長度,則只保留最左側(cè)的部分,其他部分會被截斷,此參數(shù)的缺省值為 " "。
console.log('0.0'.padStart(4,'10')) //10.0
console.log('0.0'.padStart(20))//                0.00    

String.padEnd(targetLength,padString])

  • targetLength:當(dāng)前字符串需要填充到的目標(biāo)長度。如果這個數(shù)值小于當(dāng)前字符串的長度,則返回當(dāng)前字符串本身。
  • padString:(可選) 填充字符串。如果字符串太長,使填充后的字符串長度超過了目標(biāo)長度,則只保留最左側(cè)的部分,其他部分會被截斷,此參數(shù)的缺省值為 " ";
console.log('0.0'.padEnd(4,'0')) //0.00    
console.log('0.0'.padEnd(10,'0'))//0.00000000

4.函數(shù)參數(shù)列表結(jié)尾允許逗號

這是一個不痛不癢的更新,主要作用是方便使用git進行多人協(xié)作開發(fā)時修改同一個函數(shù)減少不必要的行變更。

不使用ES8

//程序員A
var f = function(a,
  b
   ) { 
  ...
  }

//程序員B
var f = function(a,
  b,   //變更行
  c   //變更行
   ) { 
  ...
  }

//程序員C
var f = function(a,
  b,
  c,   //變更行
  d   //變更行
   ) { 
  ...
  }

使用ES8

//程序員A
var f = function(a,
  b,
   ) { 
  ...
  }

//程序員B
var f = function(a,
  b,
  c,   //變更行
   ) { 
  ...
  }

//程序員C
var f = function(a,
  b,
  c,
  d,   //變更行
   ) { 
  ...
  }

5.Object.getOwnPropertyDescriptors()

Object.getOwnPropertyDescriptors()函數(shù)用來獲取一個對象的所有自身屬性的描述符,如果沒有任何自身屬性,則返回空對象。

函數(shù)原型:

Object.getOwnPropertyDescriptors(obj)

返回obj對象的所有自身屬性的描述符,如果沒有任何自身屬性,則返回空對象。

const obj2 = {
    name: 'Jine',
    get age() { return '18' }
};
Object.getOwnPropertyDescriptors(obj2)
// {
//   age: {
//     configurable: true,
//     enumerable: true,
//     get: function age(){}, //the getter function
//     set: undefined
//   },
//   name: {
//     configurable: true,
//     enumerable: true,
//      value:"Jine",
//      writable:true
//   }
// }

總結(jié)

技術(shù)更替的車輪一直在前進中,JavaScript的規(guī)范和標(biāo)準(zhǔn)也在不斷的制定和完善。你會發(fā)現(xiàn)ECMAScript 新版的很多特性已經(jīng)是Typescript,瀏覽器或其他polyfills的一部分,就拿ES8的async/await來說,它是2017年6月被納入ECMAScript的,但我在2016年的時候就已經(jīng)開始使用這個特性了,這些特性通常由ECMAScript議員提交,然后會出現(xiàn)在在未來的某個ECMAScript版本中。

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ES7新特性 ES7在ES6的基礎(chǔ)上添加了三項內(nèi)容:求冪運算符()、Array.prototype.include...
    吳佳浩閱讀 1,712評論 0 3
  • 一、ES6簡介 ? 歷時將近6年的時間來制定的新 ECMAScript 標(biāo)準(zhǔn) ECMAScript 6(亦稱 ...
    一歲一枯榮_閱讀 6,206評論 8 25
  • 本文為阮一峰大神的《ECMAScript 6 入門》的個人版提純! babel babel負責(zé)將JS高級語法轉(zhuǎn)義,...
    Devildi已被占用閱讀 2,122評論 0 4
  • 轉(zhuǎn)發(fā)了一篇關(guān)于比較中西方教育的文章,卻引起了朋友圈朋友的抓狂和質(zhì)疑:“這個文章讀了到底要表達什么觀點呢?是要提...
    筱荀閱讀 275評論 1 0
  • 吃飯、喝酒,以及 我曾經(jīng)愛過你 默默無聞,不知孤獨 與卑微地愛著你 愛情啊,你瞧它 多像一次殘留在人世間的 毫無指...
    野孤蟬閱讀 233評論 0 6

友情鏈接更多精彩內(nèi)容