為一名前端程序員需要了解一些常用的JavaScript代碼技巧,這樣可以提高代碼效率,我們就來看看具體的內(nèi)容吧。
1.比較時間
const time1="2022-03-05 10:00:00";
const time2="2022-03-05 10:00:01";
const overtime=time1 < time2;
// overtime=> true
2.貨幣格式
const ThousandNum=num=> num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
const cash=ThousandNum(100000000);
// cash=> 100,000,000
3.隨機密碼
const Randompass=len=> Math.random().toString(36).substr(3, len);
const pass=RandomId(8);
// pass=> "7nf6tgru"
4.隨機HEX顏色值
const RandomColor=()=> "#" + Math.floor(Math.random() * 0xffffff).toString(16).padEnd(6, "0");
const color=RandomColor();
// color=> "##26330b"
5.評價星星
const StartScore=rate=> "★★★★★☆☆☆☆☆".slice(5 - rate, 10 - rate);
const start=StartScore(4);
// start=> ★★★★☆
6.獲得URL參數(shù)
const url=new URL('https://example.com?name=tom&sex=male');
const params=new URLSearchParams(url.search.replace(/\?/ig, ""));
params.has('sex'); // true
params.get("sex"); // "male"
const n1=~~ 1.19;
const n2=2.29 | 0;
const n3=3.39 >> 0;
// n1 n2 n3=> 1 2 3
2.補零
const FillZero=(num, len)=> num.toString().padStart(len, "0");
const num=FillZero(123, 5);
// num=> "00123"
3.轉(zhuǎn)換成數(shù)值
const num1=+null;
const num2=+"";
const num3=+false;
const num4=+"59";
// num1 num2 num3 num4=> 0 0 0 59
4.時間戳
const timestamp=+new Date("2022-03-07");
// timestamp=> 1646611200000
5.小數(shù)
const RoundNum=(num, decimal)=> Math.round(num * 10 ** decimal) / 10 ** decimal;
const num=RoundNum(1.2345, 2);
// num=> 1.23
6.奇偶校驗
const YEven=num=> !!(num & 1) ? "no" : "yes";
const num=YEven(1);
// num=> "no"
const num=YEven(2);
// num=> "yes"
7.獲得最小值最大值
const arr=[0, 1, 2, 3];
const min=Math.min(...arr);
const max=Math.max(...arr);
// min max=> 0 3
8.生成范圍隨機數(shù)
const RandomNum=(min, max)=> Math.floor(Math.random() * (max - min + 1)) + min;
const num=RandomNum(1, 10); // 6 每次運行可能不一樣
待續(xù)................
avaScript中的Number
對象是一個用于處理數(shù)字值的對象,它可以通過構(gòu)造函數(shù)new Number()
創(chuàng)建,或通過字面量的形式創(chuàng)建。Number
是一個全局對象,Number
對象內(nèi)部的一些屬性和方法,即可以通過Number
對象訪問,也可以全局訪問,如:parseInt()
、parseFloat
等都來自于Number
對象。
Number
對象
Number
對象屬性/方法
Number
實例方法
1. Number
對象
Number
是一個未經(jīng)封裝的用于處理數(shù)字值的對象,我們可以用它的構(gòu)造函數(shù)來創(chuàng)建一個數(shù)字對象,也可以用于將非數(shù)字對象轉(zhuǎn)換為數(shù)字。
構(gòu)造函數(shù)
new Number(value);
如上所示,為value
創(chuàng)建了一個Number
對象實例。如果value
不可轉(zhuǎn)換為數(shù)字,則返回NaN
。
非數(shù)字對象轉(zhuǎn)換為數(shù)字
Number
還可不做為構(gòu)造函數(shù)使用,即:沒有new
操作符,不做為構(gòu)造數(shù)時其主要用于類型的轉(zhuǎn)換。
Number("123") // 123
Number("12.3") // 12.3
Number("") // 0
Number("0x11") // 17
Number("0b11") // 3
Number("0o11") // 9
Number("itbilu.com") // NaN
Number("100a") // NaN
在使用Number()
函數(shù)進行數(shù)據(jù)類型轉(zhuǎn)換時,其轉(zhuǎn)換規(guī)則如下:
Boolean類型 - true
轉(zhuǎn)換為1
,false
轉(zhuǎn)換為0
數(shù)字類型 - 原樣輸出
null - 返回0
undefined - 返回NaN
字符串
空字符串 - 轉(zhuǎn)換為0
字符串中只包含數(shù)字 - 轉(zhuǎn)換成十進制數(shù)字
包含小數(shù)點 - 轉(zhuǎn)換成浮點數(shù)
其它 - 返回NaN
Object類型 - 調(diào)用對象的valueOf()
方法,再按上述規(guī)則進行轉(zhuǎn)換
使用Number()
與使用parseInt()
和parseFloat()
進行數(shù)據(jù)類型轉(zhuǎn)換的區(qū)別在于:
Number()
可以將任何類型轉(zhuǎn)換為數(shù)字,而parseInt()
和parseFloat()
只能用于字符串的轉(zhuǎn)換
Number()
會對傳入字符串進行整體轉(zhuǎn)換,而parseInt()
和parseFloat()
也會嘗試對字符串中的部分數(shù)字進行轉(zhuǎn)換。
更多區(qū)別請參考:JavaScript數(shù)字類型轉(zhuǎn)換
2. Number
對象屬性/方法
Number
對象屬性/方法是指通過Number
調(diào)用的方法,可以它們理解為靜態(tài)屬性/方法。Number
對象中的一些屬性和方法被添加到了全局對象,這些屬性和方法可以不通過Number
對而直接調(diào)用。
屬性
2.1 Number.EPSILON
- 兩個Number
的最小差
Number.EPSILON
屬性用于表示兩個Number
的之間的最小差,該屬性值接近于 2.2204460492503130808472633361816E-16
或2-52
。
2.2 Number.MAX_SAFE_INTEGER
- 最大安全整數(shù)
Number.MAX_SAFE_INTEGER
屬性表示JavaScript中最大的安全整數(shù),其值為2-53-1
2.3 Number.MAX_VALUE
- 最大值
Number.MAX_VALUE
屬性表示JavaScript中所能表示的最大正數(shù)值,其值接近于1.79E+308
,超出后會表示為Infinity
,最小負數(shù)值為-MAX_VALUE
。
2.4 Number.MIN_VALUE
- 最小值
Number.MIN_VALUE
屬性表示JavaScript中所能表示的最小正數(shù)值,其址接近于0
,最小負數(shù)值為-MIN_VALUE
。
2.5 Number.NaN
- 非數(shù)字
Number.NaN
表示“非數(shù)字”(Not-A-Number),和全局對象NaN
相同。
2.6 Number.NEGATIVE_INFINITY
- 負無窮大
Number.NEGATIVE_INFINITY
屬性表示負無窮大,會在溢出時返回該值。
2.7 Number.POSITIVE_INFINITY
- 正無窮大
Number.POSITIVE_INFINITY
屬性表示負無窮大,與全局對象Infinity
相同,會在溢出時返回該值。
2.7 Number.prototype
- 原型屬性
Number.prototype
表示構(gòu)造函數(shù)的原型,添加到原型上的屬性或方法都可以被Number
實例使用。
方法
2.8 Number.isNaN()
- 判斷值是否是NaN
Number.isNaN(value)
Number.isNaN()
方法用于判斷被檢測的值是否是NaN
,該方法是在ECMAScript 6
中定義的方法與全局方法isNaN()
并不是同一個方法。與全局方法isNaN()
相比,該方法更安全,因為它不會強制進行類型轉(zhuǎn)換。
2.9 Number.isFinite()
- 是否是有窮數(shù)
Number.isFinite(value)
Number.isFinite()
用于判斷傳入值是否是有窮數(shù),該方法是在ECMAScript 6
中定義的方法。
2.10 Number.isInteger()
- 是否是整數(shù)
Number.isInteger(value)
Number.isInteger()
用于關斷傳入的值是否是個整數(shù)。
2.11 Number.isSafeInteger()
- 是否是安全整數(shù)
Number.isSafeInteger(value)
Number.isSafeInteger()
用于關斷傳入的值是否是個整數(shù),即:值是否位于-253-1
和253-1
之間。
2.12 Number.parseFloat()
- 字符串轉(zhuǎn)換為浮點數(shù)
Number.parseFloat(string)
Number.parseFloat()
用于把一個字符串轉(zhuǎn)換為浮點數(shù),該方法與全局方法parseFloat()
一樣,在ECMAScript 6
被添加到Number
對象中。
2.13 Number.parseInt()
- 字符串轉(zhuǎn)換為整數(shù)
Number.parseInt(string)
Number.parseInt()
用于把一個字符串轉(zhuǎn)換為整數(shù),該方法與全局方法parseInt()
一樣,在ECMAScript 6
被添加到Number
對象中。
3. Number
實例方法
Number
實例繼承自Number.prototype
,所有Number
實例都有以下方法:
3.1 Number.prototype.toExponential()
- 數(shù)字的指數(shù)表示形式
numObj.toExponential(fractionDigits)
以指數(shù)形式(科學計數(shù)法)的字符串來表示Number
對象,fractionDigits
參數(shù)用于指定小數(shù)位。
var numObj=77.1234;
console.log(toExponential()); //輸出 7.71234e+1
console.log(numObj.toExponential(4)); //輸出 7.7123e+1
console.log(numObj.toExponential(2)); //輸出 7.71e+1
3.2 Number.prototype.toFixed()
- 轉(zhuǎn)換為指定小數(shù)位的字符串
numObj.toFixed([digits])
toFixed()
可以把Number
四舍五入為指定小數(shù)位數(shù)的數(shù)字字符串。
3.3 Number.prototype.toLocaleString()
- 轉(zhuǎn)換為本地形式的字符串
numObj.toLocaleString([locales [, options]])
該方法繼承自Object.prototype.toLocaleString()
用于把一個數(shù)字轉(zhuǎn)換為字符串的本地表示形式。
3.4 Number.prototype.toPrecision()
- 轉(zhuǎn)換為指定精度的字符串
numObj.toPrecision(precision)
將數(shù)字轉(zhuǎn)為一個具有指定精度的字符串
3.5 Number.prototype.toString()
- 轉(zhuǎn)換為字符串
numObj.toString([radix])
該方法繼承自Object.prototype.toString()
,用于返回Number
的字符串表示形式,radix
表示轉(zhuǎn)換基數(shù),可選值為2~36
,默認為10
。
3.6 Number.prototype.valueOf()
- 返回原始值
numObj.valueOf()
該方法繼承自Object.prototype.valueOf()
,用于返回Number
對象的原始值,該方法通常會在JavaScript內(nèi)部隱式調(diào)用。
var numObj=new Number(10);
console.log(typeof numObj); // object
var num=numObj.valueOf();
console.log(num); // 10
console.log(typeof num); // number
1.如何判斷一個變量是否為NaN?
相信大多數(shù)人應該都會想到這個不就是用運行環(huán)境提供的內(nèi)建方法 isNaN()來判斷嗎?
如下代碼:
isNaN(1); //false
isNaN("666"); //false, 恩,字符串666確實不是NaN
isNaN(5*"abc"); //true,恩,5*字符串a(chǎn)bc得到的結(jié)果確實是NaN
isNaN('what?'); //true, 啊?!! 這不并不是我想要的
事實上,isNaN的邏輯是“輸入?yún)?shù)是否不是NaN,也不是數(shù)字”。這句話我忘記在哪看過啦,我理解isNaN()的邏輯可以理解為“輸入?yún)?shù)是否可以轉(zhuǎn)化為數(shù)字”更加貼切和容易理解。所以字符串“666”的返回值為false,因為它可以轉(zhuǎn)化為數(shù)字,而字符串“what?”不能轉(zhuǎn)換為數(shù)字,故返回值為false。
那既然無法用isNaN來檢測一個值是否為NaN,那么該如何做?
有兩種辦法
第一種,根據(jù)上面的實驗,我們可以先判斷輸入?yún)?shù)的類型是否為number,再調(diào)用isNaN方法,這樣就避免了對于非數(shù)字類型的判斷錯誤。
代碼如下:
if(!Number.isNaN){
Number.isNaN=function(n){
return (
typeof n==='number' && window.isNaN(n)
)
}
}
Number.isNaN(5*'abc'); //true
Number.isNaN('what?'); //false
第二種,利用NaN的一個特性,它是JS語言中唯一一個不等于它本身的值,所以我們也可以這么寫。
if(!Number.isNaN){
Number.isNaN=function(n){
return n !==n;
}
}
Number.isNaN(5*'abc'); //true
Number.isNaN('what?'); //false
還有一種,可以利用ES6中提供的Object.is()方法來進行驗證
Object.is(5*'abc', NaN); //true
Object.is('what?', NaN); //false
如果你的代碼中仍然使用isNaN(),那么你的程序遲早會出現(xiàn)BUG。
2.如何判斷兩個浮點數(shù)相等?
在JavaScript中,0.1+0.2 不等于0.3是一個經(jīng)典問題,他時刻提醒你,對于浮點數(shù)來說,他并不能像普通數(shù)學題那樣簡單比較。究其原因,是因為在JS中,0.1+0.2的值是一個比較接近0.30000000000000004的數(shù)字,所以他并不等于0.3。
不要小看這個問題,浮點數(shù)的運算經(jīng)常會出現(xiàn),比如計算商品的折扣、計算稅費等情況下都需要對浮點數(shù)進行運算。
通常的做法是設置一個誤差范圍值,通常稱為“機器密度”,對于JavaScript來說,這個值是2的-52次冪,即Math.pow(2, -52)。
所以,可以對于浮點數(shù)進行比較時可以用下面的方法(在ES6中,Number.EPSILON是自帶的),以下代碼示例來源于網(wǎng)絡
if(!Number.EPSILON){
Number.EPSILON=Math.pow(2, -52);}
function numbersCloseEnoughToEqual(n1, n2){
return Math.abs(n1 - n2) < Number.EPSILON;}
numbersCloseEnoughToEqual(0.1+0.2, 0.3); //true
此外,需要說明的是JavaScript中最大的浮點數(shù)是Number.MAX_VALUE和Number.MIN_VALUE。
3.如何檢測一個值是否整數(shù)
如果允許使用ES6的話,可以用Number.isInterger();這個方法干凈利落。
Number.isInterger(1.000); //true
Number.isInterger(1); //true
Number.isInterger('1'); //false
如果不允許使用ES6的話,可以自行寫一個pollyFill方法。
if(!Number.isInterger){
Number.isInterger=function(num){
return (typeof num==='number') && num%1===0;
}
}
4.對于一個數(shù)字進行取整,你能說出多少種方法?
parseInt()這個方法你肯定能想到。但你可能想不到他的坑還真不少,未必是無懈可擊的方法。
這里先賣個關子在最后一個問題中,我在詳細解答。
其實還有很多很簡單有效的方法來對數(shù)字進行取整。
比如下面的方法:
8.84|0; //8
~~8.84; //8
8.84>>0; //8
這三種方法都是可以的,分別說一下:
8.84|0 或者 寫成 0|8.84 都是一樣的,從語法上看,它是讓0與指定值進行按位“或”運算,在JavaScript中,它先對指定值執(zhí)行了ToInt32的轉(zhuǎn)換,在按位進行或運算,所以最終結(jié)果就是把指定值轉(zhuǎn)換為32位的整數(shù)。
而~~8.84也是對變量進行ToInt32的轉(zhuǎn)換;再進行一步按位“取非”運算,即對每個字節(jié)進行反轉(zhuǎn);然后,再對結(jié)果再次“取非”。
那么8.84>>0的操作就同理可證了……
但是,上面的三種方法也是有其局限性的,因為他們是遵循ToInt32的轉(zhuǎn)化規(guī)范,所以他們也只能對于32位的數(shù)字進行轉(zhuǎn)換,所以再加上一個符號位,那么他們所能處理的數(shù)字范圍在2的正負31次冪之間,即-2147483648 ≤ x ≤ 2147483647。
5.當一個變量顯式類型轉(zhuǎn)換時(利用Number()方法),遵循的規(guī)則是什么?
這個問題應該會有很多種問法,比如,把一個字符串轉(zhuǎn)換為數(shù)字時,都經(jīng)歷了哪些操作?
這道題還是很考驗基礎的,一般工程師是不會記住這個細節(jié)點的。
言歸正傳,ES5規(guī)范中規(guī)定了這個抽象操作ToNumber。
對于布爾型:true的結(jié)果為1,false的結(jié)果為0;
對于undefined: 結(jié)果為NaN
對于null:結(jié)果為0
對于字符串類型:遵循數(shù)字常量的相關規(guī)則和語法。處理失敗時會返回NaN。
對于復雜類型:會先調(diào)用該值的valueOf()方法,如果有并且返回基本類型值,就是用該值進行強制類型轉(zhuǎn)換。如果沒有就是使用toString()的返回來進行強制類型轉(zhuǎn)換。
舉個栗子來加強一下記憶:
var test1={
valueOf: function(){
return 10; //valueOf方法的將被調(diào)用;
},
test2={
toString: function(){
return 666;
}
}
Number(test1) ; //10
2*test1; //20
Number(test2); //666
Number(test2)/2; //333
6.Number([])和Number([1,2,3])的值分別是什么?說明其原理?
這道題應該也算是上一道題的加強記憶了。
大家已經(jīng)知道了是先調(diào)用valueOf(),再調(diào)用toString()方法,那么空數(shù)組和[1,2,3]有什么區(qū)別呢?
因為數(shù)字的valueOf()方法返回的是數(shù)組本身,不是一個基本類型,所以還會調(diào)用toString()方法;而數(shù)組的toString()方法返回的是數(shù)組各項通過逗號拼接一起的字符串(可以理解調(diào)用了Array.prototype.join(",")方法),所以空數(shù)組返回空字符串,轉(zhuǎn)換為數(shù)組自然就是0;而數(shù)組[1,2,3]則只能轉(zhuǎn)換為NaN了.
那么,大家覺得下面的代碼應該輸出什么呢?為什么?
Number([100]); //???
7.聊一聊parseInt()方法遵循的運算規(guī)則?
之前已經(jīng)提到了,parseInt()方法含有太多坑。也許面試者會問你下面的代碼為什么可以輸出52
parseInt('52px'); //52
如果想回答上面的問題,你必須知道下面的知識點。
parseInt(string, radix);方法的接受兩個參數(shù):
要被解析的值。如果參數(shù)不是一個字符串,則將其轉(zhuǎn)換為字符串(使用toString 抽象操作)。字符串開頭的空白符將會被忽略。
一個介于2和36之間的整數(shù)(數(shù)學系統(tǒng)的基礎),表示上述字符串的基數(shù)。比如參數(shù)"10"表示使用我們通常使用的十進制數(shù)值系統(tǒng)。始終指定此參數(shù)可以消除閱讀該代碼時的困惑并且保證轉(zhuǎn)換結(jié)果可預測。當未指定基數(shù)時,不同的實現(xiàn)會產(chǎn)生不同的結(jié)果,通常將值默認為10。
返回值:
返回解析后的整數(shù)值。 如果被解析參數(shù)的第一個字符無法被轉(zhuǎn)化成數(shù)值類型,則返回 NaN。
如果 parseInt 遇到了不屬于radix參數(shù)所指定的基數(shù)中的字符那么該字符和其后的字符都將被忽略。接著返回已經(jīng)解析的整數(shù)部分。
所以,這里就明白為什么字符串'52px'會被parseInt()解析為52,因為沒有傳遞第二個參數(shù)radix,所以默認按照10進制進行解析,而字符'p'不在10進制內(nèi),所以字符'p'和后面的字符全部被忽略,直接返回數(shù)字52.
下面是parseInt()最經(jīng)典的一個坑:
parseInt(1/0, 19); //18
如果不親自一試,你絕不會相信上面代碼的輸出是18。
這里需要知道的是,1/0運算結(jié)果是“無窮”,在JavaScript中為Infinity,而這個Infinity轉(zhuǎn)換為字符串則為'Infinity',第一個字符是'I',在以19為基數(shù)時他的值為18。第二個字符‘n’不是一個有效的數(shù)字字符,所以除第一個字符外,后面的字符全部被忽略,所以最后就返回了18。
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。