【javascript】您好, 您要的ECMAScript6速記套餐到了 (一)


【前言】本文“嚴重參考” 自阮一峰老師寫的ES6文檔,在此我鄭重感謝他沉默無聲的幫助

 

總結一下ES6為 javascript中的 對象/數組/函數 這JS三巨頭所提供的更簡潔優雅的書寫方式,以及擴展的API。

對象篇

  • 屬性名簡潔表示法, 當對象的屬性名和作為屬性值的變量名名稱相同時,可只寫屬性名
var name = "彭湖灣"
var obj = { name: name }

可簡寫為

 

var name = "彭湖灣"
var obj = { name }

 

  • 如果對象的屬性是函數,可簡寫為類似於“函數聲明”的形式
var obj = {
   methods: function () {}
}

可簡寫為

 

var obj = {
  methods () {
// ... } }

 

 

 

  • 對象字面量的屬性名表達式

以前你只能對單一的對象屬性使用表達式:obj['a' + 'b'] = value
現在你可以在一個對象字面量里對屬性名使用表達式

var obj = {
  ['a' + 'b']: value
} 

 

  • Object.assign(target, source1, source2 ....) 可把source1,source2等第二個參數以后的對象合並到target

1.規則是對於同名屬性, 后面的對象會覆蓋前面的,如source1覆蓋target, source2會覆蓋source1

 

var target = { a: 1, b: 1 };
var source1 = { b: 2, c: 2 };
var source2 = { c: 3 };

Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}

 

 

 

2. Object.assign的合並功能僅止於第一層屬性,也就是說, 如果兩個合並對象(如source1和source2)有一個第一層的同名屬性,並且這個屬性也是個有屬性的對象,那么Object.assign不會“進入”位於第二層的屬性對象,對其屬性進行合並,而是簡單地用后面對象的第一層屬性替代前面對象的第一層屬性

var target = { a: { b: 'c', d: 'e' } }
var source = { a: { b: 'hello' } }
Object.assign(target, source)

結果是

{ a: { b: 'hello' } }

不是

 

{ a: { b: 'hello', d: 'e' } }

 

 

 

  • 遍歷屬性對象的幾個API對比:

1.for...in 遍歷對象自身屬性和原型中的屬性, 且要求是可枚舉屬性
2. Object.keys(obj),返回一個數組, 遍歷自身屬性, 不包括原型屬性, 且要求是可枚舉的
3. Object.getOwnPropertyNames(obj) 返回一個數組,遍歷自身屬性, 不包括原型屬性, 且不要求是可枚舉的
4.Object.values(): 和Object.keys(obj)類似,不過遍歷的是屬性值
5.Object.entries() 和Object.keys(obj)類似,不過遍歷的是屬性名/值對,返回一個二維數組
[ ["key1", "value1"], ["key2", "value2"] ]


關鍵對比


1.for...inObject.keys(obj)/Object.getOwnPropertyNames(obj), 前者取得原型中的屬性,后兩者不取
2.Object.getOwnPropertyNames(obj) 和Object.keys(obj), 都是只返回遍歷自身屬性組成的數組,前者無論是否可枚舉都返回, Object.keys(obj)只返回可枚舉屬性
3.Object.keys(obj) , Object.values(), Object.entries() 分別遍歷對象的鍵, 值,鍵值對

數組篇

  • Array.of 將一組參數作為數組元素組成數組, 如
Array.of(1, 2, 3) // [1,2,3]

 

出現原因: 彌補Array構造函數的不足:


Array構造函數因為接收參數的不同行為表現差異非常巨大
1. 當接收一個參數的時候,它會以為你傳的是數組的長度,從而創建一個對應長度的“空”數組

Array(3) // [, , ,]

2. 當接收多個參數的時候,它會以為你傳的是數組元素, 從而創建一個指定數組元素的數組

Array(1, 2, 3) // [1, 2, 3]
  • Array.from將兩類對象都轉為數組

1類數組對象(如函數內部的arguments,DOM操作產生的NodeList集合)
2 ES6新增加的Set對象, Map對象
都轉為真正的數組


轉化類數組對象

function foo() {
var args = Array.from(arguments);
// arguments從對象變成了數組
}

轉化ES6新增加的Set對象, Map對象

let namesSet = new Set(['a', 'b'])
Array.from(namesSet) // ['a', 'b']
  • find方法,用於在一個數組中找到第一個符合條件的數組元素
[1, 2, 3, -1].find((n) => n < 0)
// -1

ES5中我們可能會使用IndexOf方法來尋找一個特定的元素,但它的局限性在於indexof只能以數組元素的值作為查找條件,而find方法則更加靈活, 它提供了一個以數組元素為參數的函數供你做更加靈活的操作,並取得第一個返回true的數組元素

  • fill方法, 通過array.fill(value), 可以將array數組的所有值都寫為value

一般可以用於初始化空數組:

new Array(4).fill(1)
// [1, 1, 1,1]
  • includes方法 檢測數組中是否含有某個元素, 返回true或者false

【注意】array.indexOf(數組元素) === -1 這個常用於判斷條件的表達式可以用 includes方法去替代

[1, 2, 3].includes(2) // true
[1, 2, 3].includes(4) // false

函數篇

  • 函數參數在ES6下可以設置默認值
function log(x, y = 'World') {
   console.log(x, y);
}

log('Hello') // Hello World
  • rest 參數

可以通過“...”的運算符把接收到的函數參數合為數組放入緊跟“...”的變量中

function fn(...args) {
}
fn(1, 2, 3) // 此時 args = [1,2,3]

【注意】 函數的reset參數可以看做是擴展運算符的“逆運算”

  • name屬性

函數可取name屬性

function fn() {}
fn.name // "fn"
  • 箭頭函數

ES6引入了箭頭函數,它有幾大作用:
1. 使我們能通過一種更為簡潔的方式書寫函數
2. 箭頭函數綁定了this對象, 減少了this綁定丟失所造成的麻煩

 

  • 在javascript中, 大多數變量的查找的都是靜態的,而不是動態的, 或者說是變量所在的作用域是定義時候決定的,而不是運行時決定
  • 但this卻恰好相反, this的綁定是動態的, 是運行時決定的, 這有時候就導致了讓人苦惱的this綁定丟失問題

 

 

用一段代碼展示一下普通函數(相比於箭頭函數)所存在this綁定丟失的問題

function foo() {
  setTimeout( function () {
     console.log('id:', this.id);
  }, 100);
}

var id = 21;
foo.call({ id: 42 });
// id: 21

 

為什么輸出的是21不是42呢? 因為setTimeout里的函數是異步執行的,當調用foo.call({ id: 42 })的時候setTimeout里的函數並沒有立即得到執行,


所以setTimeout()調用的時候,它運行在與所在函數完全分離的執行環境上。這時候this指向的是window,而不是{ id: 42 } (在 ES6嚴格模式下是undefined)

 

箭頭函數的this是靜態綁定的, 所以能很好地解決這個問題:

 

function foo() {
  setTimeout(() => {
     console.log('id:', this.id);
  }, 100);
}
var id = 21;

foo.call({ id: 42 });
// id: 42

 

如果園友看到這里了, 那么請容我道個歉, 在這篇文章里, 其實多處“參考”了《ES6入門》中的例子, 比起自己親手寫的代碼,多少可能會讓讀者們感到有些難理解,因為這幾天實在挺累的,所以寫這篇文章的時候有些心力不足,見諒。

 

 資料來源

1.  MDN  https://developer.mozilla.org/zh-CN/

2.  ECMAScript 6入門 http://es6.ruanyifeng.com/

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM