es6新語法新特性總結(上)

weixin_33866037發表於2017-04-11

一、let和const命令

1-1、塊級作用域

在es6之前js是沒有塊級作用域的,es6之後,js引入塊級作用域

使用let申明變數的時候就有隱形的塊級作用域,使用const定義常量也有塊級作用域

具體的細節我在《你不知道的js》學習筆記中已經寫過了

二、變數的解構賦值

ES6 允許按照一定模式,從陣列和物件中提取值,對變數進行賦值,這被稱為解(Destructuring)。

2-1、陣列的解構賦值

本質上,這種寫法屬於“模式匹配”,只要等號兩邊的模式相同,左邊的變數就會被賦予對應的值。下面是一些使用巢狀陣列進行解構的例子。

let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3

let [ , , third] = ["foo", "bar", "baz"];
third // "baz"

let [x, , y] = [1, 2, 3];
x // 1
y // 3

let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]

let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []

2-2、物件的解構賦值

物件的解構與陣列有一個重要的不同。陣列的元素是按次序排列的,變數的取值由它的位置決定;而物件的屬性沒有次序,變數必須與屬性同名,才能取到正確的值。

let { bar, foo } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"

let { baz } = { foo: "aaa", bar: "bbb" };
baz // undefined

2-3、字串的解構賦值

字串也可以解構賦值。這是因為此時,字串被轉換成了一個類似陣列的物件。

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

2-4、數值和布林值的解構賦值

解構賦值時,如果等號右邊是數值和布林值,則會先轉為物件。

let {toString: s} = 123;
s === Number.prototype.toString // true

let {toString: s} = true;
s === Boolean.prototype.toString // true

2-5、函式引數的解構賦值

[[1, 2], [3, 4]].map(([a, b]) => a + b);
// [ 3, 7 ]
function add([x, y]){
  return x + y;
}

add([1, 2]); // 3

三、字串的擴充套件

3-1、基礎知識--UTF-8、Unicode和ASCII

ASCII:(American Standard Code for Information Interchange,美國資訊互換標準程式碼),開始計算機只在美國用。八位的位元組一共可以組合出256(2的8次方)種不同的狀態。

unicode:隨著時代的發展,很多非英語國家都有了計算機,各國也需要儲存自己的文字,所以各地區都有自己的標準。正在這時,大天使加百列及時出現了——一個叫 ISO,(國際標誰化組織)的國際組織決定著手解決這個問題。他們採用的方法很簡單:廢了所有的地區性編碼方案,重新搞一個包括了地球上所有文化、所有字母和符號的編碼!他們打算叫它”Universal Multiple-Octet Coded Character Set”,簡稱 UCS, 俗稱 “unicode“。

UTF:unicode統一規定,每個符號用三個或四個位元組表示,那麼每個英文字母前都必然有二到三個位元組是0,這對於儲存空間來說是極大的浪費,文字檔案的大小會因此大出二三倍,這是難以接受的。unicode在很長一段時間內無法推廣,直到網際網路的出現,為解決unicode如何在網路上傳輸的問題,於是面向傳輸的眾多 UTF(UCS Transfer Format)標準出現了,顧名思義,UTF-8就是每次8個位傳輸資料,而UTF-16就是每次16個位。UTF-8就是在網際網路上使用最廣的一種unicode的實現方式,這是為傳輸而設計的編碼,並使編碼無國界,這樣就可以顯示全世界上所有文化的字元了。

eg:

unicode編碼方式:
I 0049
t 0074
' 0027
s 0073
  0020
知 77e5
乎 4e4e
日 65e5
報 62a5
UTF-8編碼方式:
I 01001001
t 01110100
' 00100111
s 01110011
  00100000
知 11100111 10011111 10100101
乎 11100100 10111001 10001110
日 11100110 10010111 10100101
報 11100110 10001010 10100101

3-2、模板字串

例項程式碼如下,一看便明瞭:

// 普通字串
`In JavaScript '\n' is a line-feed.`

// 多行字串
`In JavaScript this is
 not legal.`

console.log(`string text line 1
string text line 2`);

// 字串中嵌入變數
var name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`

四、函式的擴充套件

4-1、函式引數的預設值

4-1-1、基本用法

es5用法:

function log(x, y) {
  y = y || 'World';
  console.log(x, y);
}

log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello World

es6用法:

function log(x, y = 'World') {
  console.log(x, y);
}

log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello

4-1-2、注意事項

引數變數是預設宣告的,所以不能用let或const再次宣告。

function foo(x = 5) {
  let x = 1; // error
  const x = 2; // error
}

4-1-3、與解構賦值預設值結合使用

function foo({x, y = 5}) {
  console.log(x, y);
}

foo({}) // undefined, 5
foo({x: 1}) // 1, 5
foo({x: 1, y: 2}) // 1, 2
foo() // TypeError: Cannot read property 'x' of undefined

上面程式碼使用了物件的解構賦值預設值,而沒有使用函式引數的預設值。只有當函式foo的引數是一個物件時,變數x和y才會通過解構賦值而生成。如果函式foo呼叫時引數不是物件,變數x和y就不會生成,從而報錯。如果引數物件沒有y屬性,y的預設值5才會生效。

4-1-4、函式length屬性的影響

(function (a) {}).length // 1
(function (a = 5) {}).length // 0
(function (a, b, c = 5) {}).length // 2

4-2、rest引數

ES6 引入 rest 引數(形式為“...變數名”),用於獲取函式的多餘引數,這樣就不需要使用arguments物件了。rest 引數搭配的變數是一個陣列,該變數將多餘的引數放入陣列中。

function add(...values) {
  let sum = 0;

  for (var val of values) {
    sum += val;
  }

  return sum;
}

add(2, 5, 3) // 10

下面是一個 rest 引數代替arguments變數的例子。

// arguments變數的寫法
function sortNumbers() {
  return Array.prototype.slice.call(arguments).sort();
}

// rest引數的寫法
const sortNumbers = (...numbers) => numbers.sort();

注意,rest 引數之後不能再有其他引數(即只能是最後一個引數),否則會報錯。

// 報錯
function f(a, ...b, c) {
  // ...
}

4-3、擴充套件運算子

擴充套件運算子(spread)是三個點(...)。它好比 rest 引數的逆運算,將一個陣列轉為用逗號分隔的引數序列。

console.log(...[1, 2, 3])
// 1 2 3

console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5

[...document.querySelectorAll('div')]
// [<div>, <div>, <div>]

例項使用:

function push(array, ...items) {
  array.push(...items);
}

function add(x, y) {
  return x + y;
}

var numbers = [4, 38];
add(...numbers) // 42

4-4、箭頭函式

var f = () => 5;
// 等同於
var f = function () { return 5 };

var sum = (num1, num2) => num1 + num2;
// 等同於
var sum = function(num1, num2) {
  return num1 + num2;
};

使用注意事項:


(1)函式體內的this物件,就是定義時所在的物件,而不是使用時所在的物件。

(2)不可以當作建構函式,也就是說,不可以使用new命令,否則會丟擲一個錯誤。

(3)不可以使用arguments物件,該物件在函式體內不存在。如果要用,可以用Rest引數代替。

(4)不可以使用yield命令,因此箭頭函式不能用作Generator函式。

上面四點中,第一點尤其值得注意。this物件的指向是可變的,但是在箭頭函式中,它是固定的。


閱讀原文

相關文章