你可能不知道的幾個JavaScript原生方法
自ES6發(fā)行以來,許多新的,便捷的原生方法已添加到JavaScript的新標準中。
然而,我在GitHub的代碼庫中看到了很多舊的代碼。這并不意味著它們一定是壞的,但我要介紹的這些功能將幫助你的代碼更可讀,更漂亮。
Number.isNaN vs. isNaN
NaN 是數(shù)字類型。
- typeof NaN === 'number' // true
因此,你無法區(qū)分 NaN 和數(shù)字。
甚至 Object.prototype.toString.call 都為 NaN 和數(shù)字返回 [object Number]。你可能已經(jīng)知道可以使用 isNaN 方法檢查參數(shù)是否為NaN。但是從ES6開始,number構(gòu)造函數(shù)已開始將 isNaN 作為其方法。那有什么不同?
- isNaN——檢查傳遞的值是不是數(shù)字還是不能轉(zhuǎn)換為數(shù)字。
- Number.isNaN——檢查傳遞的值是否不是數(shù)字。
下面是這個例子。
- Number.isNaN({});
- // <- false, {} is not NaN
- Number.isNaN('ponyfoo')
- // <- false, 'ponyfoo' is not NaN
- Number.isNaN(NaN)
- // <- true, NaN is NaN
- Number.isNaN('pony'/'foo')
- // <- true, 'pony'/'foo' is NaN, NaN is NaN
- isNaN({});
- // <- true, {} is not a number
- isNaN('ponyfoo')
- // <- true, 'ponyfoo' is not a number
- isNaN(NaN)
- // <- true, NaN is not a number
- isNaN('pony'/'foo')
- // <- true, 'pony'/'foo' is NaN, NaN is not a number
Number.isFinite vs. isFinite
在JavaScript中,諸如1/0之類的計算不會產(chǎn)生錯誤。相反,它為你提供了 Infinit(無限),這是一個全局屬性。
那么,如何檢查一個值是否是Infinit呢?你不能,但是你可以用 isFinite 和 Number.isFinite 來檢查一個值是否是有限值。
它們的工作原理基本相同,但彼此之間略有不同。
- isFinite——檢查傳遞的值是否有限。如果傳遞的值的類型不是數(shù)字,則將其轉(zhuǎn)換為數(shù)字。
- Number.isFinite——檢查傳遞的值是否有限。傳遞的值不會轉(zhuǎn)換為數(shù)字。
示例:
- Number.isFinite(Infinity) // false
- isFinite(Infinity) // false
- Number.isFinite(NaN) // false
- isFinite(NaN) // false
- Number.isFinite(2e64) // true
- isFinite(2e64) // true
- Number.isFinite(undefined) // false
- isFinite(undefined) // false
- Number.isFinite(null) // false
- isFinite(null) // true
- Number.isFinite('0') // false
- isFinite('0') // true
Math.floor vs. Math.trunc
在過去,當你需要把數(shù)字取整時你可能會用 Math.floor。但是從現(xiàn)在開始,如果你真正想要的只是整數(shù)部分,請嘗試使用 Math.trunc。
- Math.floor——返回小于或等于給定數(shù)字的最大整數(shù)。
- Math.trunc——截斷點和右邊的數(shù)字。
基本上,如果給定數(shù)為正,它們將為你返回完全相同的結(jié)果。但是,如果給定數(shù)為負數(shù),結(jié)果將有所不同。
- Math.floor(1.23) // 1
- Math.trunc(1.23) // 1
- Math.floor(-5.3) // -6
- Math.trunc(-5.3) // -5
- Math.floor(-0.1) // -1
- Math.trunc(-0.1) // -0
Array.prototype.indexOf vs. Array.prototype.includes
當你在給定數(shù)組中尋找某個值時,如何找到它?我已經(jīng)看到很多開發(fā)人員都使用 Array.prototype.indexOf,如以下示例所示。
- const arr = [1, 2, 3, 4];
- if (arr.indexOf(1) > -1) {
- ...
- }
他們的區(qū)別如下:
- Array.prototype.indexOf——返回可以在數(shù)組中找到給定元素的第一個索引;如果不存在,則返回 -1
- Array.prototype.includes——檢查給定數(shù)組是否包含你要查找的特定值,并返回 true / false 作為結(jié)果
示例:
- const students = ['Hong', 'James', 'Mark', 'James'];
- students.indexOf('Mark') // 1
- students.includes('James') // true
- students.indexOf('Sam') // -1
- students.includes('Sam') // false
小心!由于Unicode差異,傳遞的值區(qū)分大小寫。
String.prototype.repeat vs. 手動循環(huán)
在添加這個功能之前,你制作字符串的方式是復制字符串,比如 abcabcabc,然后將其串聯(lián)成一個空的字符串,無論你想要多少次,都可以將其串聯(lián)起來。
- var str = 'abc';
- var res = '';
- var copyTimes = 3;
- for (var i = 0; i < copyTimes; i += 1) {
- for (var j = 0; j < str.length; j += 1) {
- res += str[j];
- }
- }
但這太長了,非常混亂,有時很難閱讀。為此,可以使用 String.prototype.repeat。你要做的就是傳遞數(shù)字,該數(shù)字表示你要復制字符串的次數(shù)。
- 'abc'.repeat(3) // "abcabcabc"
- 'hi '.repeat(2) // "hi hi "
- 'empty'.repeat(0) // ""
- 'empty'.repeat(null) // ""
- 'empty'.repeat(undefined) // ""
- 'empty'.repeat(NaN) // ""
- 'error'.repeat(-1) // RangeError
- 'error'.repeat(Infinity) // RangeError
傳入的值不能為負數(shù),而且必須小于無窮大,不能是溢出的最大字符串大小。
String.prototype.match vs. String.prototype.includes
要檢查字符串中是否包含某些單詞,有兩種方法:match 和 includes。
- String.prototype.match——采用RegExp類型的參數(shù),可以使用RegExp中所有支持的標志。
- String.prototype.includes——采用兩個參數(shù),searchString 作為第一個參數(shù),而 position 作為第二個參數(shù)。如果 position 沒有通過,將使用默認值 0。
區(qū)別在于,includes是區(qū)分大小寫的,而 match 則不區(qū)分大小寫。你可以將 i 標志放在RegExp中,以使其不區(qū)分大小寫。
- const name = 'jane';
- const nameReg = /jane/i;
- const str = 'Jane is a student';
- str.includes(name) // false
- str.match(nameReg)
- // ["Jane", index: 0, input: "Jane is a student", groups: undefined]
String.prototype.concat vs. String.prototype.padStart
當你想在某些字符串的開頭附加一些字符串時,padStart 是一種功能強大的方法。
另外,concat 也可以很好地執(zhí)行這個功能。但主要的區(qū)別在于 padStart 重復了從結(jié)果字符串的第一個索引到當前字符串的第一個索引的字符串。
下面演示如何使用這個功能:
- const rep = 'abc';
- const str = 'xyz';
這是兩個字符串。我想做的是在 xyz 前面添加 rep,但不僅是一次,我希望重復幾次。padStart 需要兩個參數(shù)——新創(chuàng)建的結(jié)果字符串的總長度和將被重復的字符串。
- str.padStart(10, rep); // "abcabcaxyz"
這個功能很好用,這個功能用 concat 肯定是很難做到的,concat 也是執(zhí)行字符串附加的。
padEnd 從位置的結(jié)尾開始。
結(jié)論
在JavaScript中,有很多有趣而有用的方法并不普遍。但這并不意味著它們沒有用處。這一切都取決于你如何在各種情況下使用它們。