Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
為一名前端程序員需要了解一些常用的JavaScript代碼技巧,這樣可以提高代碼效率,我們就來看看具體的內容吧。
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參數
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.轉換成數值
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.小數
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.生成范圍隨機數
const RandomNum=(min, max)=> Math.floor(Math.random() * (max - min + 1)) + min;
const num=RandomNum(1, 10); // 6 每次運行可能不一樣
待續................
avaScript中的Number
對象是一個用于處理數字值的對象,它可以通過構造函數new Number()
創建,或通過字面量的形式創建。Number
是一個全局對象,Number
對象內部的一些屬性和方法,即可以通過Number
對象訪問,也可以全局訪問,如:parseInt()
、parseFloat
等都來自于Number
對象。
Number
對象
Number
對象屬性/方法
Number
實例方法
1. Number
對象
Number
是一個未經封裝的用于處理數字值的對象,我們可以用它的構造函數來創建一個數字對象,也可以用于將非數字對象轉換為數字。
構造函數
new Number(value);
如上所示,為value
創建了一個Number
對象實例。如果value
不可轉換為數字,則返回NaN
。
非數字對象轉換為數字
Number
還可不做為構造函數使用,即:沒有new
操作符,不做為構造數時其主要用于類型的轉換。
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()
函數進行數據類型轉換時,其轉換規則如下:
Boolean類型 - true
轉換為1
,false
轉換為0
數字類型 - 原樣輸出
null - 返回0
undefined - 返回NaN
字符串
空字符串 - 轉換為0
字符串中只包含數字 - 轉換成十進制數字
包含小數點 - 轉換成浮點數
其它 - 返回NaN
Object類型 - 調用對象的valueOf()
方法,再按上述規則進行轉換
使用Number()
與使用parseInt()
和parseFloat()
進行數據類型轉換的區別在于:
Number()
可以將任何類型轉換為數字,而parseInt()
和parseFloat()
只能用于字符串的轉換
Number()
會對傳入字符串進行整體轉換,而parseInt()
和parseFloat()
也會嘗試對字符串中的部分數字進行轉換。
更多區別請參考:JavaScript數字類型轉換
2. Number
對象屬性/方法
Number
對象屬性/方法是指通過Number
調用的方法,可以它們理解為靜態屬性/方法。Number
對象中的一些屬性和方法被添加到了全局對象,這些屬性和方法可以不通過Number
對而直接調用。
屬性
2.1 Number.EPSILON
- 兩個Number
的最小差
Number.EPSILON
屬性用于表示兩個Number
的之間的最小差,該屬性值接近于 2.2204460492503130808472633361816E-16
或2-52
。
2.2 Number.MAX_SAFE_INTEGER
- 最大安全整數
Number.MAX_SAFE_INTEGER
屬性表示JavaScript中最大的安全整數,其值為2-53-1
2.3 Number.MAX_VALUE
- 最大值
Number.MAX_VALUE
屬性表示JavaScript中所能表示的最大正數值,其值接近于1.79E+308
,超出后會表示為Infinity
,最小負數值為-MAX_VALUE
。
2.4 Number.MIN_VALUE
- 最小值
Number.MIN_VALUE
屬性表示JavaScript中所能表示的最小正數值,其址接近于0
,最小負數值為-MIN_VALUE
。
2.5 Number.NaN
- 非數字
Number.NaN
表示“非數字”(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
表示構造函數的原型,添加到原型上的屬性或方法都可以被Number
實例使用。
方法
2.8 Number.isNaN()
- 判斷值是否是NaN
Number.isNaN(value)
Number.isNaN()
方法用于判斷被檢測的值是否是NaN
,該方法是在ECMAScript 6
中定義的方法與全局方法isNaN()
并不是同一個方法。與全局方法isNaN()
相比,該方法更安全,因為它不會強制進行類型轉換。
2.9 Number.isFinite()
- 是否是有窮數
Number.isFinite(value)
Number.isFinite()
用于判斷傳入值是否是有窮數,該方法是在ECMAScript 6
中定義的方法。
2.10 Number.isInteger()
- 是否是整數
Number.isInteger(value)
Number.isInteger()
用于關斷傳入的值是否是個整數。
2.11 Number.isSafeInteger()
- 是否是安全整數
Number.isSafeInteger(value)
Number.isSafeInteger()
用于關斷傳入的值是否是個整數,即:值是否位于-253-1
和253-1
之間。
2.12 Number.parseFloat()
- 字符串轉換為浮點數
Number.parseFloat(string)
Number.parseFloat()
用于把一個字符串轉換為浮點數,該方法與全局方法parseFloat()
一樣,在ECMAScript 6
被添加到Number
對象中。
2.13 Number.parseInt()
- 字符串轉換為整數
Number.parseInt(string)
Number.parseInt()
用于把一個字符串轉換為整數,該方法與全局方法parseInt()
一樣,在ECMAScript 6
被添加到Number
對象中。
3. Number
實例方法
Number
實例繼承自Number.prototype
,所有Number
實例都有以下方法:
3.1 Number.prototype.toExponential()
- 數字的指數表示形式
numObj.toExponential(fractionDigits)
以指數形式(科學計數法)的字符串來表示Number
對象,fractionDigits
參數用于指定小數位。
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()
- 轉換為指定小數位的字符串
numObj.toFixed([digits])
toFixed()
可以把Number
四舍五入為指定小數位數的數字字符串。
3.3 Number.prototype.toLocaleString()
- 轉換為本地形式的字符串
numObj.toLocaleString([locales [, options]])
該方法繼承自Object.prototype.toLocaleString()
用于把一個數字轉換為字符串的本地表示形式。
3.4 Number.prototype.toPrecision()
- 轉換為指定精度的字符串
numObj.toPrecision(precision)
將數字轉為一個具有指定精度的字符串
3.5 Number.prototype.toString()
- 轉換為字符串
numObj.toString([radix])
該方法繼承自Object.prototype.toString()
,用于返回Number
的字符串表示形式,radix
表示轉換基數,可選值為2~36
,默認為10
。
3.6 Number.prototype.valueOf()
- 返回原始值
numObj.valueOf()
該方法繼承自Object.prototype.valueOf()
,用于返回Number
對象的原始值,該方法通常會在JavaScript內部隱式調用。
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?
相信大多數人應該都會想到這個不就是用運行環境提供的內建方法 isNaN()來判斷嗎?
如下代碼:
isNaN(1); //false
isNaN("666"); //false, 恩,字符串666確實不是NaN
isNaN(5*"abc"); //true,恩,5*字符串abc得到的結果確實是NaN
isNaN('what?'); //true, 啊?!! 這不并不是我想要的
事實上,isNaN的邏輯是“輸入參數是否不是NaN,也不是數字”。這句話我忘記在哪看過啦,我理解isNaN()的邏輯可以理解為“輸入參數是否可以轉化為數字”更加貼切和容易理解。所以字符串“666”的返回值為false,因為它可以轉化為數字,而字符串“what?”不能轉換為數字,故返回值為false。
那既然無法用isNaN來檢測一個值是否為NaN,那么該如何做?
有兩種辦法
第一種,根據上面的實驗,我們可以先判斷輸入參數的類型是否為number,再調用isNaN方法,這樣就避免了對于非數字類型的判斷錯誤。
代碼如下:
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(),那么你的程序遲早會出現BUG。
2.如何判斷兩個浮點數相等?
在JavaScript中,0.1+0.2 不等于0.3是一個經典問題,他時刻提醒你,對于浮點數來說,他并不能像普通數學題那樣簡單比較。究其原因,是因為在JS中,0.1+0.2的值是一個比較接近0.30000000000000004的數字,所以他并不等于0.3。
不要小看這個問題,浮點數的運算經常會出現,比如計算商品的折扣、計算稅費等情況下都需要對浮點數進行運算。
通常的做法是設置一個誤差范圍值,通常稱為“機器密度”,對于JavaScript來說,這個值是2的-52次冪,即Math.pow(2, -52)。
所以,可以對于浮點數進行比較時可以用下面的方法(在ES6中,Number.EPSILON是自帶的),以下代碼示例來源于網絡
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中最大的浮點數是Number.MAX_VALUE和Number.MIN_VALUE。
3.如何檢測一個值是否整數
如果允許使用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.對于一個數字進行取整,你能說出多少種方法?
parseInt()這個方法你肯定能想到。但你可能想不到他的坑還真不少,未必是無懈可擊的方法。
這里先賣個關子在最后一個問題中,我在詳細解答。
其實還有很多很簡單有效的方法來對數字進行取整。
比如下面的方法:
8.84|0; //8
~~8.84; //8
8.84>>0; //8
這三種方法都是可以的,分別說一下:
8.84|0 或者 寫成 0|8.84 都是一樣的,從語法上看,它是讓0與指定值進行按位“或”運算,在JavaScript中,它先對指定值執行了ToInt32的轉換,在按位進行或運算,所以最終結果就是把指定值轉換為32位的整數。
而~~8.84也是對變量進行ToInt32的轉換;再進行一步按位“取非”運算,即對每個字節進行反轉;然后,再對結果再次“取非”。
那么8.84>>0的操作就同理可證了……
但是,上面的三種方法也是有其局限性的,因為他們是遵循ToInt32的轉化規范,所以他們也只能對于32位的數字進行轉換,所以再加上一個符號位,那么他們所能處理的數字范圍在2的正負31次冪之間,即-2147483648 ≤ x ≤ 2147483647。
5.當一個變量顯式類型轉換時(利用Number()方法),遵循的規則是什么?
這個問題應該會有很多種問法,比如,把一個字符串轉換為數字時,都經歷了哪些操作?
這道題還是很考驗基礎的,一般工程師是不會記住這個細節點的。
言歸正傳,ES5規范中規定了這個抽象操作ToNumber。
對于布爾型:true的結果為1,false的結果為0;
對于undefined: 結果為NaN
對于null:結果為0
對于字符串類型:遵循數字常量的相關規則和語法。處理失敗時會返回NaN。
對于復雜類型:會先調用該值的valueOf()方法,如果有并且返回基本類型值,就是用該值進行強制類型轉換。如果沒有就是使用toString()的返回來進行強制類型轉換。
舉個栗子來加強一下記憶:
var test1={
valueOf: function(){
return 10; //valueOf方法的將被調用;
},
test2={
toString: function(){
return 666;
}
}
Number(test1) ; //10
2*test1; //20
Number(test2); //666
Number(test2)/2; //333
6.Number([])和Number([1,2,3])的值分別是什么?說明其原理?
這道題應該也算是上一道題的加強記憶了。
大家已經知道了是先調用valueOf(),再調用toString()方法,那么空數組和[1,2,3]有什么區別呢?
因為數字的valueOf()方法返回的是數組本身,不是一個基本類型,所以還會調用toString()方法;而數組的toString()方法返回的是數組各項通過逗號拼接一起的字符串(可以理解調用了Array.prototype.join(",")方法),所以空數組返回空字符串,轉換為數組自然就是0;而數組[1,2,3]則只能轉換為NaN了.
那么,大家覺得下面的代碼應該輸出什么呢?為什么?
Number([100]); //???
7.聊一聊parseInt()方法遵循的運算規則?
之前已經提到了,parseInt()方法含有太多坑。也許面試者會問你下面的代碼為什么可以輸出52
parseInt('52px'); //52
如果想回答上面的問題,你必須知道下面的知識點。
parseInt(string, radix);方法的接受兩個參數:
要被解析的值。如果參數不是一個字符串,則將其轉換為字符串(使用toString 抽象操作)。字符串開頭的空白符將會被忽略。
一個介于2和36之間的整數(數學系統的基礎),表示上述字符串的基數。比如參數"10"表示使用我們通常使用的十進制數值系統。始終指定此參數可以消除閱讀該代碼時的困惑并且保證轉換結果可預測。當未指定基數時,不同的實現會產生不同的結果,通常將值默認為10。
返回值:
返回解析后的整數值。 如果被解析參數的第一個字符無法被轉化成數值類型,則返回 NaN。
如果 parseInt 遇到了不屬于radix參數所指定的基數中的字符那么該字符和其后的字符都將被忽略。接著返回已經解析的整數部分。
所以,這里就明白為什么字符串'52px'會被parseInt()解析為52,因為沒有傳遞第二個參數radix,所以默認按照10進制進行解析,而字符'p'不在10進制內,所以字符'p'和后面的字符全部被忽略,直接返回數字52.
下面是parseInt()最經典的一個坑:
parseInt(1/0, 19); //18
如果不親自一試,你絕不會相信上面代碼的輸出是18。
這里需要知道的是,1/0運算結果是“無窮”,在JavaScript中為Infinity,而這個Infinity轉換為字符串則為'Infinity',第一個字符是'I',在以19為基數時他的值為18。第二個字符‘n’不是一個有效的數字字符,所以除第一個字符外,后面的字符全部被忽略,所以最后就返回了18。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。