1. 程式人生 > >程序員必須知道的六大ES6新特性

程序員必須知道的六大ES6新特性

log 註意 string 回調函數 三種 -c 新的 構造 但是

一 、字符串擴展

1、傳統上,JavaScript只有indexOf方法,可以用來確定一個字符串是否包含在另一個字符串中。ES6又提供了三種新方法。
includes():返回布爾值,表示是否找到了參數字符串。
startsWith():返回布爾值,表示參數字符串是否在源字符串的頭部。
endsWith():返回布爾值,表示參數字符串是否在源字符串的尾部。

var s = ‘Hello world!‘;
console.log(s.startsWith(‘Hello‘)); // true
console.log(s.endsWith(‘!‘)); // true
console.log(s.includes(‘o‘)); // true



//這三個方法都支持第二個參數,表示開始搜索的位置。
var s = ‘Hello world!‘;
s.startsWith(‘world‘, 6) // true
s.endsWith(‘Hello‘, 5) // true
s.includes(‘Hello‘, 6) // false

2、padStart() padEnd()
ES2017 引入了字符串補全長度的功能。如果某個字符串不夠指定長度,會在頭部或尾部補全。padStart()用於頭部補全,padEnd()用於尾部補全。

‘x‘.padStart(5, ‘ab‘) // ‘ababx‘
‘x‘.padStart(4, ‘ab‘) // ‘abax‘



‘x‘.padEnd(5, ‘ab‘) // ‘xabab‘
‘x‘.padEnd(4, ‘ab‘) // ‘xaba‘
//上面代碼中,padStart和padEnd一共接受兩個參數,第一個參數用來指定字符串的最小長度,第二個參數是用來補全的字符串。

//如果原字符串的長度,等於或大於指定的最小長度,則返回原字符串。
‘xxx‘.padStart(2, ‘ab‘) // ‘xxx‘
‘xxx‘.padEnd(2, ‘ab‘) // ‘xxx‘

//如果用來補全的字符串與原字符串,兩者的長度之和超過了指定的最小長度,則會截去超出位數的補全字符串。
‘abc‘.padStart(10, ‘0123456789‘)
// ‘0123456abc‘


//如果省略第二個參數,默認使用空格補全長度。
‘x‘.padStart(4) // ‘ x‘
‘x‘.padEnd(4) // ‘x ‘

//padStart的常見用途是為數值補全指定位數。下面代碼生成10位的數值字符串。
‘1‘.padStart(10, ‘0‘) // "0000000001"
‘12‘.padStart(10, ‘0‘) // "0000000012"
‘123456‘.padStart(10, ‘0‘) // "0000123456"

//另一個用途是提示字符串格式。
‘12‘.padStart(10, ‘YYYY-MM-DD‘) // "YYYY-MM-12"
‘09-12‘.padStart(10, ‘YYYY-MM-DD‘) // "YYYY-09-12"

3、模板字符串

//傳統的JavaScript語言,輸出模板通常是這樣寫的。
$(‘#result‘).append(
‘There are <b>‘ + basket.count + ‘</b> ‘ +
‘items in your basket, ‘ +
‘<em>‘ + basket.onSale +
‘</em> are on sale!‘
);
//上面這種寫法相當繁瑣不方便,ES6引入了模板字符串解決這個問題。

$(‘#result‘).append(`
There are <b>${basket.count}</b> items
in your basket, <em>${basket.onSale}</em>
are on sale!
`);

var first="劉";
var last="夢";
//var name= ‘Your name is ‘+ first+ ‘ ‘+ last+ ‘.‘;
var name1= `Yournameis${first}${last}`;
console.log(name);

多行字符串
如果使用模板字符串表示多行字符串,所有的空格和縮進都會被保留在輸出之中。
如果你不想要這個換行,可以使用trim方法消除它。
console.log(`In JavaScript ‘\n‘ is a line-feed.`);

console.log(`In JavaScript this is
not legal.`);

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

大括號內部可以放入任意的JavaScript表達式,可以進行運算,以及引用對象屬性。
var x = 1;
var y = 2;

`${x} + ${y} = ${x + y}`
// "1 + 2 = 3"

`${x} + ${y * 2} = ${x + y * 2}`
// "1 + 4 = 5"

var obj = {x: 1, y: 2};
`${obj.x + obj.y}`
// 3


二、數值的擴展

//1、指數運算符 ES2016 新增了一個指數運算符(**)。
2 ** 2 // 4
2 ** 3 // 8
//指數運算符可以與等號結合,形成一個新的賦值運算符(**=)。

let a = 1.5;
a **= 2;
// 等同於 a = a * a;

let b = 4;
b **= 3;
// 等同於 b = b * b * b;

四、函數的擴展


1、函數的默認值:ES6 之前,不能直接為函數的參數指定默認值,只能采用變通的方法。

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

log(‘Hello‘) // Hello World
log(‘Hello‘, ‘China‘) // Hello China
log(‘Hello‘, ‘‘) // Hello World
//上面代碼檢查函數log的參數y有沒有賦值,如果沒有,則指定默認值為World。這種寫法的缺點在於,如果參數y賦值了,但是對應的布爾值為false,則該賦值不起作用。就像上面代碼的最後一行,參數y等於空字符,結果被改為默認值。

//為了避免這個問題,通常需要先判斷一下參數y是否被賦值,如果沒有,再等於默認值。
if (typeof y === ‘undefined‘) {
y = ‘World‘;
}

//ES6 允許為函數的參數設置默認值,即直接寫在參數定義的後面。
function log(x, y = ‘World‘) {
console.log(x, y);
}
log(‘Hello‘) // Hello World
log(‘Hello‘, ‘China‘) // Hello China
log(‘Hello‘, ‘‘) // Hello

//參數變量是默認聲明的,所以不能用let或const再次聲明。
function foo(x = 5) {
let x = 1; // error
const x = 2; // error
}
//使用參數默認值時,函數不能有同名參數。
function foo(x, x, y = 1) {
// ...
}
// SyntaxError: Duplicate parameter name not allowed in this context

//參數默認值的位置:通常情況下,定義了默認值的參數,應該是函數的尾參數。因為這樣比較容易看出來,到底省略了哪些參數。如果非尾部的參數設置默認值,實際上這個參數是沒法省略的。
// 例一
function f(x = 1, y) {
return [x, y];
}
f() // [1, undefined]
f(2) // [2, undefined])
f(, 1) // 報錯
f(undefined, 1) // [1, 1]

// 例二
function f(x, y = 5, z) {
return [x, y, z];
}
f() // [undefined, 5, undefined]
f(1) // [1, 5, undefined]
f(1, ,2) // 報錯
f(1, undefined, 2) // [1, 5, 2]
//上面代碼中,有默認值的參數都不是尾參數。這時,無法只省略該參數,而不省略它後面的參數,除非顯式輸入undefined。

//如果傳入undefined,將觸發該參數等於默認值,null則沒有這個效果。
function foo(x = 5, y = 6) {
console.log(x, y);
}

foo(undefined, null)
// 5 null

2、作用域:一旦設置了參數的默認值,函數進行聲明初始化時,參數會形成一個單獨的作用域(context)。等到初始化結束,這個作用域就會消失。這種語法行為,在不設置參數默認值時,是不會出現的。
var x = 1;
function f(x, y = x) {
console.log(y);
}

f(2) // 2
//上面代碼中,參數y的默認值等於變量x。調用函數f時,參數形成一個單獨的作用域。在這個作用域裏面,默認值變量x指向第一個參數x,而不是全局變量x,所以輸出是2。
3、name屬性:函數的name屬性,返回該函數的函數名。
function foo() {}
foo.name // "foo"

//ES6 對這個屬性的行為做出了一些修改。如果將一個匿名函數賦值給一個變量,ES5 的name屬性,會返回空字符串,而 ES6 的name屬性會返回實際的函數名。
var f = function () {};
// ES5
console.log(f.name); // ""

// ES6
console.log(f.name); // "f"

//如果將一個具名函數賦值給一個變量,則 ES5 和 ES6 的name屬性都返回這個具名函數原本的名字。
const bar = function baz() {};
// ES5
console.log(bar.name); // "baz"

// ES6
console.log(bar.name); // "baz"


4、ES6 允許使用“箭頭”(=>)定義函數。
var f = v => v;
//上面的箭頭函數等同於:

var f = function(v) {
return v;
};

//如果箭頭函數不需要參數或需要多個參數,就使用一個圓括號代表參數部分。
var f = () => 5;
// 等同於
var f = function () { return 5 };

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

//如果箭頭函數的代碼塊部分多於一條語句,就要使用大括號將它們括起來,並且使用return語句返回。
var sum = (num1, num2) => { return num1 + num2; }

//由於大括號被解釋為代碼塊,所以如果箭頭函數直接返回一個對象,必須在對象外面加上括號。
var getTempItem = id => ({ id: id, name: "Temp" });

//箭頭函數可以與變量解構結合使用。
const full = ({ first, last }) => first + ‘ ‘ + last;
// 等同於
function full(person) {
return person.first + ‘ ‘ + person.last;
}

//箭頭函數使得表達更加簡潔。
const isEven = n => n % 2 == 0;
const square = n => n * n;

//箭頭函數的一個用處是簡化回調函數。
// 正常函數寫法
[1,2,3].map(function (x) {
return x * x;
});

// 箭頭函數寫法
[1,2,3].map(x => x * x);

/*箭頭函數有幾個使用註意點。

(1)函數體內的this對象,就是定義時所在的對象,而不是使用時所在的對象。

(2)不可以當作構造函數,也就是說,不可以使用new命令,否則會拋出一個錯誤。

(3)不可以使用arguments對象,該對象在函數體內不存在。如果要用,可以用 rest 參數代替。

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


五、Symbol
ES6 引入了一種新的原始數據類型Symbol,表示獨一無二的值。它是 JavaScript 語言的第七種數據類型,前六種是:undefined、null、布爾值(Boolean)、字符串(String)、數值(Number)、對象(Object)。
Symbol 值通過Symbol函數生成。這就是說,對象的屬性名現在可以有兩種類型,一種是原來就有的字符串,另一種就是新增的 Symbol 類型。凡是屬性名屬於 Symbol 類型,就都是獨一無二的,可以保證不會與其他屬性名產生沖突。

let s = Symbol();
console.log(typeof s);
// "symbol"
//上面代碼中,變量s就是一個獨一無二的值。typeof運算符的結果,表明變量s是 Symbol 數據類型,而不是字符串之類的其他類型。

var s1 = Symbol(‘foo‘);
var s2 = Symbol(‘bar‘);

console.log(s1); // Symbol(foo)
console.log(s2); // Symbol(bar)

console.log(s1.toString()); // "Symbol(foo)"
console.log(s2.toString()); // "Symbol(bar)"
// Symbol函數可以接受一個字符串作為參數,表示對 Symbol 實例的描述,主要是為了在控制臺顯示,或者轉為字符串時,比較容易區分。
//上面代碼中,s1和s2是兩個 Symbol 值。如果不加參數,它們在控制臺的輸出都是Symbol(),不利於區分。有了參數以後,就等於為它們加上了描述,輸出的時候就能夠分清,到底是哪一個值。



六、解構:
let [a, b, c] = [1, 2, 3];
這種寫法屬於“模式匹配”,只要等號兩邊的模式相同,左邊的變量就會被賦予對應的值。下面是一些使用嵌套數組進行解構的例子。*/

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

alert(foo);
alert(bar);


/*let [ , , third] = ["foo", "bar", "baz"];
//third "baz"
alert(third);*/

/*let [x, , y] = [1, 2, 3];
// x 1
//y 3
alert(x);*/


/*let [head, ...tail] = [1, 2, 3, 4];
//head 1
//tail [2, 3, 4]
alert(head);*/

/*let [x, y, ...z] = [‘a‘];
// x "a"
//y undefined
//z []
alert(x);
alert(y);
alert(z);*/

程序員必須知道的六大ES6新特性