JavaScript (ES8/ES2017)新特性

前言

  • 內容主要來自網絡,主要來自 MDN

  • ES(JavaScript)是一門大家都要努力學習語言,也是一門努力不讓開發者精通的語言。

  • ES678 大部分功能能通過Polyfill或者Babel來解決。
    也就是說ES5能實現這些功能

/**
 * ie78 沒有 trim方法
 * @returns {string}
 */
if(!String.prototype.trim){
    String.prototype.trim = function(){
        return this.replace(/(^\s*)|(\s*$)/g, "");
}

還有一些 語法糖 ,語法糖就是指那些沒有給語言添加新功能,而只是對人類來說更“甜蜜”的語法。
比如 class ES5的繼承

function Base(opt){
}

function SubClass(opt){
    Base.call(this,opt);
}
SubClass.prototype = new Page;//繼承屬性
SubClass.prototype.constructor = SubClass;//防止指向父類的constructor
var obj = new SubClass(opt);//實例化對象

ES6繼承的寫法:

class Base(opt){
}

class SubClass(opt) extends Base {
    super(opt);
}

let obj = new SubClass(opt);

1、什麼是ES、ES8(隨便講講,你們隨便聽聽)

  • ECMAScript:一個由 ECMA International 進行標準化,TC39 委員會進行監督的語言。通常用於指代標準本身。
  • JavaScript:ECMAScript 標準的各種實現的最常用稱呼。這個術語並不侷限於某個特定版本的 ECMAScript 規範,並且可能被用於任何不同程度的任意版本的 ECMAScript 的實現。
  • ECMAScript5 (ES5) :ECMAScript 的第五版修訂,於 2009 年完成標準化。這個規範在所有現代瀏覽器中都相當完全的實現了。
  • ECMAScript 6 (ES6) / ECMAScript 2015 (ES2015):ECMAScript 的第六版修訂,於 2015 年**完成標準化。這個標準被部分實現於大部分現代瀏覽器。可以查閱這張兼容性表來查看不同瀏覽器和工具的實現情況。
  • ECMAScript 2016(ES7):第七版 ECMAScript 修訂,只加了Array.prototype.includes、Exponentiation Operator(求冥運算)
  • ECMAScript2017(ES8) :第八版 ECMAScript 修訂
  • ECMAScript Proposals:被考慮加入未來版本 ECMAScript標準的特性與語法提案,他們需要經歷五個階段:Strawman(稻草人),Proposal(提議),Draft(草案),Candidate(候選)以及 Finished (完成)。

2、padStart&padEnd(字符串填充)

2.1 存在的意義

  • 以等寬字體顯示平整的數據。
  • 在文件名或URL中添加計數或ID:’001.txt’。
  • 對齊控制檯輸出: ‘Test 001: ’。
  • 打印具有固定位數的十六進制或二進制數字:’0x00FF’

2.2 語法

String.prototype.padStart(targetLength [, padString])
String.prototype.padEnd(targetLength [, padString])
  • 參數
    • targetLength 當前字符串需要填充到的目標長度。如果當前字符串原本就達到了該長度,那麼該方法什麼都不會做,直接返回原字符串。
    • padString填充字符串。如果在填充過程中發現用不完這一整個填充字符串,則優先用左側部分,能用多少用多少。該參數爲可選參數,默認值爲空格 " "
  • 返回值
    • 在原字符串頭部/尾部填充指定的填充字符串直到目標長度所形成的新字符串

2.3 例子

'abc'.padStart(10);         // "       abc"
'abc'.padStart(10, "100");  // "1001001abc"
'abc'.padStart(6,"123465"); // "123abc"
'abc'.padStart(8, "0");     // "00000abc"
'abc'.padStart(1);          // "abc"

2.4 兼容性

注意:這是一個實驗中的功能,未來瀏覽器可能會改變語法和功能。

瀏覽器 Chrome Edge Firefox Internet Explorer Opera Safari
支持 57 15 48 No 44 10
瀏覽器 Android webview Chrome for Android Edge mobile Firefox for Android IE mobile Opera Android iOS Safari
支持 ? 57 Yes 48 No ? 10

2.5 其他:

  • 爲什麼這兩個填充方法不叫做 padLeft 和 padRight ?
    • 對於雙向或從右到左的語言, left 和 right 這兩個詞顯然容易混淆。因此,padStart 和 padEnd 的命名遵循了現有的 startsWith 和 endsWith 名稱。

3、Object.values(obj)(遍歷對象值)

方法返回一個給定對象自己的所有可枚舉屬性值的數組,值的順序與使用for…in循環的順序相同 ( 區別在於 for-in 循環枚舉原型鏈中的屬性 )。

3.1 存在的意義

  • 以前有Object.keys,可以遍歷對象的Key,所以遍歷value的話只能這樣獲取:
var values = [];
Object.keys(obj).forEach(function(key){
    values.push(obj[key])
})

現在只需要

var values = Object.values(obj)

3.2 語法

Object.values(obj)
  • 參數

    • obj 被返回可枚舉屬性值的對象。(TODO:拓展可枚舉屬性值)
  • 返回值

    • 一個包含對象自身的所有可枚舉屬性鍵值的數組

3.3 例子

var obj = { foo: "bar", baz: 42 };
console.log(Object.values(obj)); // ['bar', 42]

// array like object 長得像有序下標數組的對象
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.values(obj)); // ['a', 'b', 'c']

// array like object with random key ordering 長得像無序下標數組的對象 
var an_obj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.values(an_obj)); // ['b', 'c', 'a']注意順序

// getFoo is property which isn't enumerable 可枚舉屬性值
var my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; } } });
my_obj.foo = "bar";
console.log(Object.values(my_obj)); // ['bar']

// non-object argument will be coerced to an object 字符串
console.log(Object.values("foo")); // ['f', 'o', 'o'] 實際上string 是 char 的數組['f', 'o', 'o']

3.4 兼容性

Feature Chrome Edge Firefox Internet Explorer Opera Safari
Basic support 54 Yes 47 No Yes 10.1
瀏覽器 Android webview Chrome for Android Edge mobile Firefox for Android IE mobile Opera Android iOS Safari
支持 54 54 Yes 48 No ? 10

3.5 其他相關:

  • Enumerability and ownership of properties
  • Object.keys()
  • Object.entries()
  • Object.prototype.propertyIsEnumerable()
  • Object.create()
  • Object.getOwnPropertyNames()

4、Object.entries(obj) (遍歷對象鍵值對)

Object.entries()方法返回一個給定對象自身可枚舉屬性的鍵值對數組,其排列與使用 for…in 循環遍歷該對象時返回的順序一致(區別在於 for-in 循環也枚舉原型鏈中的屬性)。

4.1 存在的意義

  • 由於ES5,ES6,ES7並沒有提供遍歷對象的鍵-值對屬性的接口,所以可能官方腦袋一熱,有了獲取對象鍵集合的方法,也有了獲取對象值集合的方法,那就再來一個鍵值對吧。

4.2 語法

Object.entries(obj)
  • 參數
    • obj 被返回可枚舉屬性值的對象。(TODO:拓展可枚舉屬性值)
  • 返回值
    • 給定對象自身可枚舉屬性的鍵值對數組。

4.3 例子

const obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]

// array like object
const obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.entries(obj)); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]

// array like object with random key ordering
const anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.entries(anObj)); // [ ['2', 'b'], ['7', 'c'], ['100', 'a'] ]

// getFoo is property which isn't enumerable
const myObj = Object.create({}, { getFoo: { value() { return this.foo; } } });
myObj.foo = 'bar';
console.log(Object.entries(myObj)); // [ ['foo', 'bar'] ]

// non-object argument will be coerced to an object
console.log(Object.entries('foo')); // [ ['0', 'f'], ['1', 'o'], ['2', 'o'] ]

// iterate through key-value gracefully
const obj = { a: 5, b: 7, c: 9 };
for (const [key, value] of Object.entries(obj)) {
  console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
}

// Or, using array extras
Object.entries(obj).forEach(([key, value]) => {
console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
});
  • new Map() 構造函數接受一個可迭代的entries。藉助Object.entries方法你可以很容易的將Object轉換爲Map:
var obj = { foo: "bar", baz: 42 }; 
var map = new Map(Object.entries(obj));
console.log(map); // Map { foo: "bar", baz: 42 }

4.4 兼容性

瀏覽器 Chrome Edge Firefox Internet Explorer Opera Safari
支持 54 Yes 47 No Yes 10.1
手機瀏覽器 Android webview Chrome for Android Edge mobile Firefox for Android IE mobile Opera Android iOS Safari
支持 54 54 Yes 47 No No No

4.5 其他相關

  • 屬性的可枚舉性和所有權
  • Object.keys()
  • Object.values()
  • Object.prototype.propertyIsEnumerable()
  • Object.create()
  • Object.getOwnPropertyNames()

5、async、await(異步處理)

像同步一樣寫異步的代碼

5.1 存在的意義

js一個重大的特點就是異步,但是人類的思維模式天然是同步的。所以要把異步和同步的流程化統一起來。
直接上例子:

  • 回調地獄
getData(data => {
  getMoreData(data2 =>{
    getMoreData(data3 =>{
      
    })
  })
})
  • JQuery解決方法
var def1 = $.Deferred();
var def2 = $.Deferred();
var def3 = $.Deferred();
def1.done(def2.resolve)
def2.done(def3.resolve)
def3.done(function(){})
  • ES6 Promise
new Promise().then().then()...

後面的雖然解決了回調地獄,但是本質上還是回調。

  • 對比java/javascript redis操作
  • java
Jedis jedis = new Jedis("localhost");
System.out.println("連接成功");
jedis.set("key", "Hello world");
String key = jedis.get("key")
System.out.println("redis 存儲的字符串爲: "+ key)
  • javascript
let client = redis.createClient(RDS_PORT,.RDS_HOST,.RDS_OPTS);
client.select(RDS_DATABASE)
client.hmset("key", "Hello world",function(){
  client.hmget("key",function(data){
    console.log(data)
  })
});

5.2 語法

async function name([param[, param[, ... param]]]) { statements }
[return_value] = await expression; 
  • 參數
  • async:要傳遞給函數的參數的名稱
  • 返回值

5.3 例子

ES7,asyns和await 更配哦

function resolveAfter2Seconds(x) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(x);
    }, 2000);
  });
}

async function add1(x) {
  var a = resolveAfter2Seconds(20);
  var b = resolveAfter2Seconds(30);
  return x + await a + await b;
}
var  ajax = () => {
	return new Promise(resolve =>{
		setTimeout(() => {
      		resolve("done");
    	}, 2000);
	})
}

async function getData(x) {
  var a = await ajax();
  console.log(a)
}
  • await:如果該值不是一個 Promise,await 會把該值轉換爲已正常處理的Promise,然後等待其處理結果。
async function myFetch(){ 
    let res = await fetch("http://www.baidu.com/json")
    let result = await res.json()
    return result
}

myFetch().then(data => console.log(JSON.stringify(data)))

5.4 兼容性

瀏覽器 Chrome Edge Firefox Internet Explorer Opera Safari
支持 55 Yes 52 No 42 10.1
手機瀏覽器 Android webview Chrome for Android Edge mobile Firefox for Android IE mobile Opera Android iOS Safari
支持 Yes 55 Yes 52 No 42 10.1

5.5 其他相關

  • AsyncFunction object

6、Object.getOwnPropertyDescriptor ()

方法返回指定對象上一個自有屬性對應的屬性描述符。(自有屬性指的是直接賦予該對象的屬性,不需要從原型鏈上進行查找的屬性)。

6.1 存在的意義

  • 該方法的提出目的,主要是爲了解決Object.assign()無法正確拷貝get屬性和set屬性的問題。。

6.2 語法

Object.getOwnPropertyDescriptor(obj, prop)
  • 參數
    • obj 需要查找的目標對象
    • prop目標對象內屬性名稱(String類型)
  • 返回值
    • 如果指定的屬性存在於對象上,則返回其屬性描述符對象(property descriptor),否則返回 undefined
    • 一個屬性描述符是一個記錄,由下面屬性當中的某些組成的:
      • value該屬性的值(僅針對數據屬性描述符有效)
      • writable 當且僅當屬性的值可以被改變時爲true。(僅針對數據屬性描述有效)
      • get 獲取該屬性的訪問器函數(getter)。如果沒有訪問器, 該值爲undefined。(僅針對包含訪問器或設置器的屬性描述有效)
      • set 獲取該屬性的設置器函數(setter)。 如果沒有設置器, 該值爲undefined。(僅針對包含訪問器或設置器的屬性描述有效)
      • configurable 當且僅當指定對象的屬性描述可以被改變或者屬性可被刪除時,爲true。
      • enumerable當且僅當指定對象的屬性可以被枚舉出時,爲 true。

6.3 例子

//拷貝對象
var obj = {
	a:"a",
	get b(){return "b"}
}
var obj1 = Object.assign({},obj)
var obj2 = Object.create(  
    Object.getPrototypeOf(obj),  
    Object.getOwnPropertyDescriptors(obj)  
)
console.log(obj)//{a: "a"}
console.log(JSON.stringify(obj))//{"a":"a","b":"b"}

console.log(obj1)//{a: "a", b: "b"}
console.log(JSON.stringify(obj1))//{"a":"a","b":"b"}

console.log(obj2)//{a: "a"}
console.log(JSON.stringify(obj2))//{"a":"a","b":"b"}
var obj = {
	a:"a",
	get b(){return "b"}
}
JSON.stringify(Object.getOwnPropertyDescriptors(obj))
/*
{
    "a":{
        "value":"a",
        "writable":true,
        "enumerable":true,
        "configurable":true
    },
    "b":{
        "enumerable":true,
        "configurable":true
    }
}
*/

6.4 兼容性

瀏覽器 Chrome Edge Firefox Internet Explorer Opera Safari
支持 ? ? 50 (50) ? ? ?
手機瀏覽器 Android webview Chrome for Android Edge mobile Firefox for Android IE mobile Opera Android iOS Safari
支持 ? ? ? 50.0 (50) ? ? ?

6.5 其他相關

7、函數參數列表與調用中的尾部逗號

允許在參數定義和函數調用後面使用逗號。

7.1 存在的意義

  • 重新排列元素項比較簡單,如果你要改變最後一個元素項的位置,你不必添加和刪除逗號。
  • 幫助版本控制系統跟蹤實際發生的變化。

7.2 語法

function foo(
    param1,
    param2,
) {}

foo(param1,param3,)

7.3 例子

  • 同語法

7.4 兼容性

管好自己的雙手,不要用這個方式寫就好了。

7.5 其他相關:

8、共享內存與原子操作

SharedArrayBuffer 對象用來表示一個通用的,固定長度的原始二進制數據緩衝區,類似於 ArrayBuffer 對象。對象,但它們可以用來在共享內存上創建視圖。與 ArrayBuffer 不同的是,SharedArrayBuffer 不能被分離。

8.1 存在的意義

一個新的低級別Atomics命名空間對象和一個SharedArrayBuffer構造函數,來作爲更高級別併發抽象的原始構建塊。共享多個service worker和核心線程之間的SharedArrayBuffer對象的數據。在worker之間共享數據,改善worker之間的協調。

8.2 語法

new SharedArrayBuffer(length)

8.3 例子

8.4 兼容性

8.5 其他相關:

傳送門

9、Array.prototype.includes

includes() 方法用來判斷一個數組是否包含一個指定的值,如果是,酌情返回 true或 false。

9.1 存在的意義

includes() 方法用來判斷一個數組是否包含一個指定的值,如果是,酌情返回 true或 false。

9.2 語法

arr.includes(searchElement)
arr.includes(searchElement, fromIndex)
  • 參數
  • searchElement 需要查找的元素值。
  • fromIndex(可選) 從該索引處開始查找 searchElement。如果爲負值,則按升序從 array.length + fromIndex 的索引開始搜索。默認爲 0。
  • 返回值
  • 一個 Boolean。

9.3 例子

[1, 2, 3].includes(2);     // true
[1, 2, 3].includes(4);     // false
[1, 2, 3].includes(3, 3);  // false
[1, 2, 3].includes(3, -1); // true
[1, 2, NaN].includes(NaN); // true
  • 如果fromIndex 大於等於數組長度 ,則返回 false 。該數組不會被搜索。
var arr = ['a', 'b', 'c'];
arr.includes('c', 3);   //false
arr.includes('c', 100); // false
  • 如果 fromIndex 爲負值,計算出的索引將作爲開始搜索searchElement的位置。如果計算出的索引小於 0,則整個數組都會被搜索
var arr = ['a', 'b', 'c'];

arr.includes('a', -100); // true
arr.includes('b', -100); // true
arr.includes('c', -100); // true
  • includes() 方法有意設計爲通用方法。它不要求this值是數組對象,所以它可以被用於其他類型的對象 (比如類數組對象)。下面的例子展示了 在函數的arguments對象上調用的includes() 方法。
(function() {
  console.log([].includes.call(arguments, 'a')); // true
  console.log([].includes.call(arguments, 'd')); // false
})('a','b','c');

9.4 兼容性

9.5 其他相關:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章