ECMAScript 6 入門
includes(), startsWith(), endsWith() § ?
傳統(tǒng)上,JavaScript 只有indexOf方法笑窜,可以用來確定一個(gè)字符串是否包含在另一個(gè)字符串中。ES6 又提供了三種新方法脯宿。
- includes():返回布爾值策泣,表示是否找到了參數(shù)字符串器罐。
- startsWith():返回布爾值,表示參數(shù)字符串是否在原字符串的頭部兄纺。
- endsWith():返回布爾值大溜,表示參數(shù)字符串是否在原字符串的尾部。
let s = 'Hello world!';
s.startsWith('Hello') // true
s.endsWith('!') // true
s.includes('o') // true
這三個(gè)方法都支持第二個(gè)參數(shù)估脆,表示開始搜索的位置钦奋。
let s = 'Hello world!';
s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false
上面代碼表示,使用第二個(gè)參數(shù)n時(shí)疙赠,endsWith的行為與其他兩個(gè)方法有所不同付材。它針對(duì)前n個(gè)字符,而其他兩個(gè)方法針對(duì)從第n個(gè)位置直到字符串結(jié)束圃阳。
repeat() § ?
repeat方法返回一個(gè)新字符串厌衔,表示將原字符串重復(fù)n次。
'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
'na'.repeat(0) // ""
參數(shù)如果是小數(shù)捍岳,會(huì)被取整富寿。
'na'.repeat(2.9) // "nana"
如果repeat的參數(shù)是負(fù)數(shù)或者Infinity,會(huì)報(bào)錯(cuò)锣夹。
'na'.repeat(Infinity)
// RangeError
'na'.repeat(-1)
// RangeError
但是页徐,如果參數(shù)是 0 到-1 之間的小數(shù),則等同于 0银萍,這是因?yàn)闀?huì)先進(jìn)行取整運(yùn)算变勇。0 到-1 之間的小數(shù),取整以后等于-0贴唇,repeat視同為 0搀绣。
'na'.repeat(-0.9) // ""
參數(shù)NaN等同于 0飞袋。
'na'.repeat(NaN) // ""
如果repeat的參數(shù)是字符串,則會(huì)先轉(zhuǎn)換成數(shù)字链患。
'na'.repeat('na') // ""
'na'.repeat('3') // "nanana"
padStart()巧鸭,padEnd() § ?
ES2017 引入了字符串補(bǔ)全長度的功能。如果某個(gè)字符串不夠指定長度麻捻,會(huì)在頭部或尾部補(bǔ)全蹄皱。padStart()用于頭部補(bǔ)全,padEnd()用于尾部補(bǔ)全芯肤。
'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'
'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'
上面代碼中巷折,padStart和padEnd一共接受兩個(gè)參數(shù),第一個(gè)參數(shù)用來指定字符串的最小長度崖咨,第二個(gè)參數(shù)是用來補(bǔ)全的字符串锻拘。
padStart的常見用途是為數(shù)值補(bǔ)全指定位數(shù)。下面代碼生成 10 位的數(shù)值字符串击蹲。
'1'.padStart(10, '0') // "0000000001"
'12'.padStart(10, '0') // "0000000012"
'123456'.padStart(10, '0') // "0000123456"
另一個(gè)用途是提示字符串格式署拟。
'12'.padStart(10, 'YYYY-MM-DD') // "YYYY-MM-12"
'09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12"
模板字符串 § ?
傳統(tǒng)的 JavaScript 語言,輸出模板通常是這樣寫的歌豺。
$('#result').append(
'There are <b>' + basket.count + '</b> ' +
'items in your basket, ' +
'<em>' + basket.onSale +
'</em> are on sale!'
);
上面這種寫法相當(dāng)繁瑣不方便推穷,ES6 引入了模板字符串解決這個(gè)問題。
$('#result').append(`
There are <b>${basket.count}</b> items
in your basket, <em>${basket.onSale}</em>
are on sale!
`);
大括號(hào)內(nèi)部可以放入任意的 JavaScript 表達(dá)式类咧,可以進(jìn)行運(yùn)算馒铃,以及引用對(duì)象屬性。
let x = 1;
let y = 2;
`${x} + ${y} = ${x + y}`
// "1 + 2 = 3"
`${x} + ${y * 2} = ${x + y * 2}`
// "1 + 4 = 5"
let obj = {x: 1, y: 2};
`${obj.x + obj.y}`
// "3"
模板字符串之中還能調(diào)用函數(shù)痕惋。
function fn() {
return "Hello World";
}
`foo ${fn()} bar`
// foo Hello World bar
如果大括號(hào)中的值不是字符串区宇,將按照一般的規(guī)則轉(zhuǎn)為字符串。比如值戳,大括號(hào)中是一個(gè)對(duì)象议谷,將默認(rèn)調(diào)用對(duì)象的toString方法。
// 變量place沒有聲明
let msg = `Hello, ${place}`;
// 報(bào)錯(cuò)
如果模板字符串中的變量沒有聲明堕虹,將報(bào)錯(cuò)卧晓。
模板字符串甚至還能嵌套。
const tmpl = addrs => `
<table>
${addrs.map(addr => `
<tr><td>${addr.first}</td></tr>
<tr><td>${addr.last}</td></tr>
`).join('')}
</table>
`;
上面代碼中赴捞,模板字符串的變量之中逼裆,又嵌入了另一個(gè)模板字符串,使用方法如下螟炫。
const data = [
{ first: '<Jane>', last: 'Bond' },
{ first: 'Lars', last: '<Croft>' },
];
console.log(tmpl(data));
// <table>
//
// <tr><td><Jane></td></tr>
// <tr><td>Bond</td></tr>
//
// <tr><td>Lars</td></tr>
// <tr><td><Croft></td></tr>
//
// </table>
如果需要引用模板字符串本身波附,在需要時(shí)執(zhí)行艺晴,可以像下面這樣寫昼钻。
// 寫法一
let str = 'return ' + '`Hello ${name}!`';
let func = new Function('name', str);
func('Jack') // "Hello Jack!"
// 寫法二
let str = '(name) => `Hello ${name}!`';
let func = eval.call(null, str);
func('Jack') // "Hello Jack!"
實(shí)例:模板編譯 § ?
let template = `
<ul>
<% for(let i=0; i < data.supplies.length; i++) { %>
<li><%= data.supplies[i] %></li>
<% } %>
</ul>
`;
上面代碼在模板字符串之中掸屡,放置了一個(gè)常規(guī)模板。該模板使用<%...%>放置 JavaScript 代碼然评,使用<%= ... %>輸出 JavaScript 表達(dá)式仅财。
Math 對(duì)象的擴(kuò)展 § ?
ES6 在 Math 對(duì)象上新增了 17 個(gè)與數(shù)學(xué)相關(guān)的方法。所有這些方法都是靜態(tài)方法碗淌,只能在 Math 對(duì)象上調(diào)用盏求。
Math.trunc() § ?
Math.trunc方法用于去除一個(gè)數(shù)的小數(shù)部分,返回整數(shù)部分亿眠。
Math.trunc(4.1) // 4
Math.trunc(4.9) // 4
Math.trunc(-4.1) // -4
Math.trunc(-4.9) // -4
Math.trunc(-0.1234) // -0
對(duì)于非數(shù)值碎罚,Math.trunc內(nèi)部使用Number方法將其先轉(zhuǎn)為數(shù)值。
Math.trunc('123.456') // 123
Math.trunc(true) //1
Math.trunc(false) // 0
Math.trunc(null) // 0
對(duì)于空值和無法截取整數(shù)的值纳像,返回NaN荆烈。
Math.sign() § ?
Math.sign方法用來判斷一個(gè)數(shù)到底是正數(shù)、負(fù)數(shù)竟趾、還是零憔购。對(duì)于非數(shù)值,會(huì)先將其轉(zhuǎn)換為數(shù)值岔帽。
它會(huì)返回五種值玫鸟。
參數(shù)為正數(shù),返回+1犀勒;
參數(shù)為負(fù)數(shù)屎飘,返回-1;
參數(shù)為 0贾费,返回0枚碗;
參數(shù)為-0,返回-0;
其他值铸本,返回NaN肮雨。
Math.sign(-5) // -1
Math.sign(5) // +1
Math.sign(0) // +0
Math.sign(-0) // -0
Math.sign(NaN) // NaN
如果參數(shù)是非數(shù)值,會(huì)自動(dòng)轉(zhuǎn)為數(shù)值箱玷。對(duì)于那些無法轉(zhuǎn)為數(shù)值的值怨规,會(huì)返回NaN。
Math.cbrt() § ?
Math.cbrt方法用于計(jì)算一個(gè)數(shù)的立方根锡足。
Math.cbrt(-1) // -1
Math.cbrt(0) // 0
Math.cbrt(1) // 1
Math.cbrt(2) // 1.2599210498948734
Math.clz32() § ?
JavaScript 的整數(shù)使用 32 位二進(jìn)制形式表示波丰,Math.clz32方法返回一個(gè)數(shù)的 32 位無符號(hào)整數(shù)形式有多少個(gè)前導(dǎo) 0。
Math.clz32(0) // 32
Math.clz32(1) // 31
Math.clz32(1000) // 22
Math.clz32(0b01000000000000000000000000000000) // 1
Math.clz32(0b00100000000000000000000000000000) // 2
上面代碼中舶得,0 的二進(jìn)制形式全為 0掰烟,所以有 32 個(gè)前導(dǎo) 0;1 的二進(jìn)制形式是0b1,只占 1 位纫骑,所以 32 位之中有 31 個(gè)前導(dǎo) 0蝎亚;1000 的二進(jìn)制形式是0b1111101000,一共有 10 位先馆,所以 32 位之中有 22 個(gè)前導(dǎo) 0发框。
clz32這個(gè)函數(shù)名就來自”count leading zero bits in 32-bit binary representation of a number“(計(jì)算一個(gè)數(shù)的 32 位二進(jìn)制形式的前導(dǎo) 0 的個(gè)數(shù))的縮寫。
左移運(yùn)算符(<<)與Math.clz32方法直接相關(guān)煤墙。
Math.clz32(0) // 32
Math.clz32(1) // 31
Math.clz32(1 << 1) // 30
Math.clz32(1 << 2) // 29
Math.clz32(1 << 29) // 2
對(duì)于小數(shù)梅惯,Math.clz32方法只考慮整數(shù)部分。
Math.clz32(3.2) // 30
Math.clz32(3.9) // 30
對(duì)于空值或其他類型的值仿野,Math.clz32方法會(huì)將它們先轉(zhuǎn)為數(shù)值铣减,然后再計(jì)算。
Math.clz32() // 32
Math.clz32(NaN) // 32
Math.clz32(Infinity) // 32
Math.clz32(null) // 32
Math.clz32('foo') // 32
Math.clz32([]) // 32
Math.clz32({}) // 32
Math.clz32(true) // 31
Math.imul() § ?
Math.imul方法返回兩個(gè)數(shù)以 32 位帶符號(hào)整數(shù)形式相乘的結(jié)果脚作,返回的也是一個(gè) 32 位的帶符號(hào)整數(shù)徙歼。
Math.imul(2, 4) // 8
Math.imul(-1, 8) // -8
Math.imul(-2, -2) // 4
如果只考慮最后 32 位,大多數(shù)情況下鳖枕,Math.imul(a, b)與a * b的結(jié)果是相同的魄梯,即該方法等同于(a * b)|0的效果(超過 32 位的部分溢出)。之所以需要部署這個(gè)方法宾符,是因?yàn)?JavaScript 有精度限制酿秸,超過 2 的 53 次方的值無法精確表示。這就是說魏烫,對(duì)于那些很大的數(shù)的乘法辣苏,低位數(shù)值往往都是不精確的,Math.imul方法可以返回正確的低位數(shù)值哄褒。
Math.fround() § ?
Math.fround方法返回一個(gè)數(shù)的32位單精度浮點(diǎn)數(shù)形式稀蟋。
對(duì)于32位單精度格式來說,數(shù)值精度是24個(gè)二進(jìn)制位(1 位隱藏位與 23 位有效位)呐赡,所以對(duì)于 -224 至 224 之間的整數(shù)(不含兩個(gè)端點(diǎn))退客,返回結(jié)果與參數(shù)本身一致。
Math.fround(0) // 0
Math.fround(1) // 1
Math.fround(2 ** 24 - 1) // 16777215
如果參數(shù)的絕對(duì)值大于 224链嘀,返回的結(jié)果便開始丟失精度萌狂。
Math.fround(2 ** 24) // 16777216
Math.fround(2 ** 24 + 1) // 16777216
Math.hypot() § ?
Math.hypot方法返回所有參數(shù)的平方和的平方根。
Math.hypot(3, 4); // 5
Math.hypot(3, 4, 5); // 7.0710678118654755
Math.hypot(); // 0
Math.hypot(NaN); // NaN
Math.hypot(3, 4, 'foo'); // NaN
Math.hypot(3, 4, '5'); // 7.0710678118654755
Math.hypot(-3); // 3
上面代碼中怀泊,3 的平方加上 4 的平方茫藏,等于 5 的平方。
如果參數(shù)不是數(shù)值霹琼,Math.hypot方法會(huì)將其轉(zhuǎn)為數(shù)值务傲。只要有一個(gè)參數(shù)無法轉(zhuǎn)為數(shù)值凉当,就會(huì)返回 NaN。
對(duì)數(shù)方法 § ?
ES6 新增了 4 個(gè)對(duì)數(shù)相關(guān)方法售葡。
(1) Math.expm1()
Math.expm1(x)返回 ex - 1看杭,即Math.exp(x) - 1。
Math.expm1(-1) // -0.6321205588285577
Math.expm1(0) // 0
Math.expm1(1) // 1.718281828459045
(2)Math.log1p()
Math.log1p(x)方法返回1 + x的自然對(duì)數(shù)天通,即Math.log(1 + x)。如果x小于-1熄驼,返回NaN像寒。
Math.log1p(1) // 0.6931471805599453
Math.log1p(0) // 0
Math.log1p(-1) // -Infinity
Math.log1p(-2) // NaN
(3)Math.log10()
Math.log10(x)返回以 10 為底的x的對(duì)數(shù)。如果x小于 0瓜贾,則返回 NaN诺祸。
Math.log10(2) // 0.3010299956639812
Math.log10(1) // 0
Math.log10(0) // -Infinity
Math.log10(-2) // NaN
Math.log10(100000) // 5
(4)Math.log2()
Math.log2(3) // 1.584962500721156
Math.log2(2) // 1
Math.log2(1) // 0
Math.log2(0) // -Infinity
Math.log2(-2) // NaN
Math.log2(1024) // 10
Math.log2(1 << 29) // 29
雙曲函數(shù)方法
ES6 新增了 6 個(gè)雙曲函數(shù)方法。
Math.sinh(x) 返回x的雙曲正弦(hyperbolic sine)
Math.cosh(x) 返回x的雙曲余弦(hyperbolic cosine)
Math.tanh(x) 返回x的雙曲正切(hyperbolic tangent)
Math.asinh(x) 返回x的反雙曲正弦(inverse hyperbolic sine)
Math.acosh(x) 返回x的反雙曲余弦(inverse hyperbolic cosine)
Math.atanh(x) 返回x的反雙曲正切(inverse hyperbolic tangent)
指數(shù)運(yùn)算符 § ?
ES2016 新增了一個(gè)指數(shù)運(yùn)算符(**)祭芦。
2 ** 2 // 4
2 ** 3 // 8
指數(shù)運(yùn)算符可以與等號(hào)結(jié)合筷笨,形成一個(gè)新的賦值運(yùn)算符(**=)。
let a = 1.5;
a **= 2;
// 等同于 a = a * a;
let b = 4;
b **= 3;
// 等同于 b = b * b * b;
注意龟劲,在 V8 引擎中胃夏,指數(shù)運(yùn)算符與Math.pow的實(shí)現(xiàn)不相同,對(duì)于特別大的運(yùn)算結(jié)果昌跌,兩者會(huì)有細(xì)微的差異仰禀。
Math.pow(99, 99)
// 3.697296376497263e+197
99 ** 99
// 3.697296376497268e+197