亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

給初學(xué)者:JavaScript 的常見注意點(diǎn)

blair / 2895人閱讀

摘要:上篇說了一些中數(shù)組操作的常見誤區(qū),這次來總結(jié)一下初學(xué)者常見的其他易錯(cuò)點(diǎn)。小心它的精度問題。這就是存在的唯一意義。而包括在內(nèi)所有瀏覽器所以對于日期字符串,請注意字符串中是使用橫杠還是斜杠??紤]到負(fù)數(shù)時(shí)區(qū)的問題,不推薦將小時(shí)數(shù)清零的做法。

上篇說了一些 JS 中數(shù)組操作的常見誤區(qū),這次來總結(jié)一下初學(xué)者常見的其他易錯(cuò)點(diǎn)。

寫立即執(zhí)行函數(shù)時(shí)前置 void

立即執(zhí)行函數(shù)(IIFE)在 JS 非常常用,作用就是構(gòu)造一個(gè)函數(shù)級的變量作用域。常見的寫法如下:

(function () {
  // code
})();

這樣寫可能會被 JS 理解成為一個(gè)函數(shù)調(diào)用

var a = 1
(function () { // Uncaught TypeError: 1 is not a function
})()

從今天改變習(xí)慣,這樣寫:

void function () {
  // code
}();

有些人喜歡以 ! 打頭,個(gè)人習(xí)慣問題。

在 standardjs 規(guī)范日益流行的今天,忽略行尾分號成為了主流(但是筆者不喜歡),更要改變這個(gè)習(xí)慣

注:standardjs 本身禁止行首括號(https://standardjs.com/readme...)

檢查一個(gè)變量是否為對象之前,首先判斷其值是否為 null

雖然不愿承認(rèn),JS 標(biāo)準(zhǔn)說:

typeof null === "object" // true

毋庸置疑的,null 不具備作為對象類型的基本特征,是原始類型。這是一個(gè)廣為人知的 JS 的 bug,,它從 JS 誕生開始就存在,從未、而且永遠(yuǎn)不會被修復(fù)

我們不必去探究它的黑歷史,但是我們寫代碼時(shí)判斷一個(gè)變量的類型時(shí),首先需要判斷它是否為 null

if (someVal !== null && typeof someVal === "object") {
  // someVal 是一個(gè)對象
}
做數(shù)值計(jì)算時(shí),注意 JS 數(shù)值類型的精度

在 JS 里,所有的 number 原始值都是一個(gè)雙精度浮點(diǎn)數(shù),對應(yīng) Java 的 double 類型,對應(yīng)標(biāo)準(zhǔn) IEEE754。小心它的精度問題。

做整數(shù)處理時(shí),注意數(shù)值的大小

JS 最大可存儲的安全整數(shù)(不存在精度問題)為 9007199254740991 (16位,Number.MAX_SAFE_INTEGER ),注意比 Java 的 long 類型最大整數(shù) 9223372036854775807 (19位) 小幾個(gè)數(shù)量級,所以有時(shí) JS 的 number 類型是不能精確存儲 Java 的整數(shù)的(當(dāng)然通常情況下不是問題)。

問題通常出在前后端數(shù)據(jù)傳輸上。數(shù)據(jù)庫中的主鍵通常是一個(gè)自增長的長整型數(shù),有可能會超出 JS 的安全整數(shù)范圍,這時(shí)請考慮使用字符串傳輸。

做小數(shù)計(jì)算時(shí),注意浮點(diǎn)數(shù)的精度問題

例如:0.1+0.2 => 0.30000000000000004,0.4-0.3 => 0.10000000000000003

將小數(shù)轉(zhuǎn)化為字符串時(shí),永遠(yuǎn)記得使用 toFixed 取小數(shù)點(diǎn)后若干位數(shù)字:

(0.1 + 0.2).toFixed(2) === "0.30"

比較小數(shù)相等時(shí),切記不要直接使用 ===,而要使用相減取絕對值的方式(表示兩數(shù)相差在一定范圍內(nèi)即認(rèn)為他們相等)。

0.1+0.2 === 0.3 // false
Math.abs(0.1+0.2 - 0.3) <= 1e-10 // true
NaN !== NaN

NaN 之所以 NB,因?yàn)樗幸粋€(gè)獨(dú)一無二的特性。對!獨(dú)一無二!那就是:

NaN === NaN // false
var a = NaN; a === a // false

NaN 不等于它自己。你可以使用這個(gè)特性判斷一個(gè)變量是否為 NaN,一個(gè)變量如果不等于它自己,這個(gè)變量一定是 NaN。

還有一個(gè)方式是使用 Number.isNaN。注意如果不已知這個(gè)變量的類型是數(shù)字時(shí),不要使用 isNaN 做判斷,因?yàn)?isNaN 有個(gè)很詭異的特性:它會先將待判斷的變量轉(zhuǎn)換為數(shù)值類型。

isNaN("abc") // true
isNaN("123") // false
isNaN("") // false
isNaN([]) // false
isNaN({}) // true

永遠(yuǎn)不要寫 someVal === NaN

正確使用 parseInt

首先parseInt接受兩個(gè)參數(shù),第一個(gè)參數(shù)為待parse的字符串(如果不是字符串則會首先轉(zhuǎn)換為字符串);第二個(gè)參數(shù)為使用的進(jìn)制數(shù)。

如果不傳第二個(gè)參數(shù),則進(jìn)制由第一個(gè)參數(shù)決定。什么意思呢?比如以 0x 開頭的字符串,會被解析為16進(jìn)制數(shù)。

我們知道以數(shù)字 0 開頭的數(shù)字為8進(jìn)制數(shù)(非嚴(yán)格模式),比如 011 === 9,0 本身也是8進(jìn)制數(shù)。那么問題來了, parseInt("011") = ?

答案是看瀏覽器。目前絕大多數(shù)瀏覽器都會作為10進(jìn)制數(shù)解析,結(jié)果為11。但是還有一些老舊的瀏覽器以8進(jìn)制數(shù)解析(例如IE8和一批老Android瀏覽器)

所以如果你非要用 parseInt:

parseInt 使用規(guī)則一:請傳入第二個(gè)參數(shù)

回到 parseInt 本身的含義。顧名思義這個(gè)函數(shù)是在parse,被parse的一定是個(gè)字符串。如果第一個(gè)參數(shù)不是字符串,那么會首先被轉(zhuǎn)換為字符串。

問:parseInt(0.0000000008) =?

答:

String(0.0000000008) => "8e-10"

parseInt("8e-10") => 8

自己打開調(diào)試器去試

parseInt使用規(guī)則二:永遠(yuǎn)不要使用parseInt給小數(shù)取整

建議對于數(shù)值轉(zhuǎn)換一概使用強(qiáng)制轉(zhuǎn)換函數(shù) Number,如果你JS用6了可以使用 +(正號)。
如果需要對某個(gè)數(shù)字取整,建議使用 Math.trunc。如果你能確定數(shù)值在 32 位以內(nèi),可以使用 x | 0~~x 等方式

parseInt的用處在于轉(zhuǎn)換一些CSS里帶單位的值:parseInt("10px", 10) => 10。但這里建議使用parseFloat,可以解析小數(shù)又沒有進(jìn)制問題。

除了用于比較 null 或 undefined,永遠(yuǎn)不要使用非嚴(yán)格相等 ==

絕不要簡單的把非嚴(yán)格相等 == 理解為兩者表示的數(shù)字一樣,它有一套非常復(fù)雜的轉(zhuǎn)換規(guī)則:它會先將 %% 轉(zhuǎn)換為 @@,然后把 !! 轉(zhuǎn)換為 **,如果 %%?? 類型,還會 xx 一把……

看不懂對吧,我相信你就算看懂了也記不住的。不然請問:

"true" == true // => false
"true" == false // => false
[] == {} // => false
[] == [] // => false

關(guān)于非嚴(yán)格相等,你只需要記住這個(gè)規(guī)則:

null == null // => true
undefined == undefined  // => true
null == undefined // => true
undefined == null // => true
x == null // => false (x 非 null 或 undefined)
x == undefined // => false (x 非 null 或 undefined)

簡言之:

x == null // 或 x == undefined

是最簡單的判斷 x 為 null 或 undefined 的方式,相對應(yīng)的

x != null // 或 x != undefined

是最簡單的判斷 x 非 null 和 undefined 的方式。這就是 == 存在的唯一意義。

日期處理 new Date(year, month, day) 注意其參數(shù)的數(shù)值范圍

由于可能的歷史傳承原因,JS 內(nèi)置對象 Date 的構(gòu)造函數(shù)比較特殊。

如果 year 是 0 ~ 99 之間,year 默認(rèn)加 1900。比如 1 代表公元 1901 年,99 代表公元 1999 年,100 代表公元 100 年。(你問 -1 是幾?公元前 1 年。。。)

month 從 0 開始算。0 代表一月,1 代表二月,以此類推。12 代表下一年的一月(自動(dòng)進(jìn)位)

第一點(diǎn)不知道也沒什么,畢竟一般不會操作公元 99 年之前的時(shí)間。但第二點(diǎn)就很容易出錯(cuò),切記它是以 0 開始的數(shù)字。

這樣得到的日期對象是本地時(shí)間(采用客戶端時(shí)區(qū))

new Date(dateString) 注意瀏覽器時(shí)區(qū)問題以及瀏覽器兼容性

時(shí)常有后端接口返回一個(gè)日期字符串的情況:

new Date("2018-01-01") // => "2018/1/1 08:00:00" 新版瀏覽器,IE 11
new Date("2018-01-01") // => "2018/1/1 00:00:00" 某些舊版安卓
new Date("2018-01-01") // => "Invalid Date" IE 8(這個(gè)忽略。。。)

可以看到,瀏覽器基本都是把日期字符串當(dāng)做 UTC 時(shí)間處理的。而

new Date("2018/01/01") // => "2018/1/1 00:00:00" 包括 IE 8 在內(nèi)所有瀏覽器

所以對于日期字符串,請注意字符串中是使用橫杠還是斜杠。對于橫杠可以考慮將 - 替換成 /,或者補(bǔ)全完整的帶時(shí)區(qū)的 ISO8601 字符串??紤]到負(fù)數(shù)時(shí)區(qū)的問題,不推薦將小時(shí)數(shù)清零的做法。

PS:將日期對象取當(dāng)天 0 點(diǎn)為 date.setHours(0, 0, 0, 0)
PS2:取當(dāng)前時(shí)間的 Unix 時(shí)間戳可以 Date.now()

補(bǔ):慎用 || 填充默認(rèn)值

這反而是 JS 老鳥更容易犯的錯(cuò)誤。給用戶傳入的對象填充默認(rèn)值是很常見的行為,他們總是隨手就寫:

config.prop1 = config.prop1 || 233;
config.prop2 = config.prop2 || "balabala";

expr1 || expr2 的意思是:如果expr1能轉(zhuǎn)換成true則返回expr1,否則返回expr2

expr1 || expr2 <=> Boolean(expr1) ? expr1 : expr2

哪些值不能轉(zhuǎn)換為 true 呢?

null

undefined

NaN

0 !!!

空字符串("") !!!

如果用戶指定了傳入?yún)?shù)的值為 0 或者是空字符串的配置項(xiàng),它的值就會被強(qiáng)制替換為默認(rèn)值,然而實(shí)際上只有 undefined 應(yīng)該被認(rèn)為是用戶沒有指定其值(語義上可以這樣理解:null 表示 用戶讓你給他把這個(gè)位置空著;而 undefined 表示 用戶沒發(fā)表意見

所以就應(yīng)該是這樣:

config.prop1 = config.prop1 !== undefined ? config.prop1 : 233;
config.prop2 = config.prop2 !== undefined ? config.prop2 : "balabala";

很長。。。你可以搞個(gè)全局的函數(shù)簡化這一操作,或者考慮使用 lodash 的 defaults 方法

歡迎補(bǔ)充

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/90724.html

相關(guān)文章

  • 學(xué)者JavaScript 中數(shù)組操作注意點(diǎn)

    摘要:使用遍歷數(shù)組有三點(diǎn)問題遍歷順序不固定引擎不保證對象的遍歷順序。作為原生函數(shù),和自身操作字符串的速度是很快的。由于沒有返回值返回,所以它的回調(diào)函數(shù)通常是包含副作用的,否則這個(gè)寫了毫無意義。接受一個(gè)回調(diào)函數(shù),你可以提前,相當(dāng)于手寫循環(huán)中的。 不要用 for_in 遍歷數(shù)組 這是 JavaScript 初學(xué)者常見的誤區(qū)。for_in 用于遍歷對象中包括原型鏈上的所有可枚舉的(enumerab...

    tianyu 評論0 收藏0
  • Elm入門實(shí)踐(一)——基礎(chǔ)篇

    摘要:由于內(nèi)容較多,計(jì)劃分四篇,大致內(nèi)容分布如下基礎(chǔ)篇介紹基礎(chǔ)。接下來讓我們補(bǔ)全這一部分在第行我們引入了模塊中函數(shù),可以理解為當(dāng)事件發(fā)生時(shí),它會輸出一個(gè)消息。我們有了數(shù)據(jù),具備行為的視圖,按行為改變數(shù)據(jù)的邏輯,卻沒有將它們粘合成一個(gè)應(yīng)用。 簡介 Elm 是一門專注于Web前端的純函數(shù)式語言。你可能沒聽說過它,但一定聽說過Redux,而Redux的核心reducer就是受到了Elm的啟發(fā)。 隨...

    junbaor 評論0 收藏0
  • 學(xué)者學(xué)習(xí)JAVASCRIPT很吃力怎么辦?到底該如何學(xué)習(xí)JS?

    摘要:給初學(xué)者的印象總是那么的雜而亂,相信很多初學(xué)者都在找輕松學(xué)習(xí)的途徑。通常學(xué)了很久的基礎(chǔ)之后,變量函數(shù)對象你也都略知一二,但一到公司開發(fā)項(xiàng)目的時(shí)候,卻又難以下手。 Js給初學(xué)者的印象總是那么的雜而亂,相信很多初學(xué)者都在找輕松學(xué)習(xí)Js的途徑。在這里給大家總結(jié)一些學(xué)習(xí)Js的經(jīng)驗(yàn),希望能給后來的學(xué)習(xí)者探索出一條輕松學(xué)習(xí)Js之路。Js給人那種感覺的原因多半是因?yàn)樗缦碌奶攸c(diǎn):A:本身知識很抽象、...

    WrBug 評論0 收藏0
  • 前端基礎(chǔ)入門

    摘要:手把手教你做個(gè)人火的時(shí)候,隨便一個(gè)都能賺的盆滿缽滿,但是,個(gè)人沒有服務(wù)端,沒有美工,似乎就不能開發(fā)了,真的是這樣的嗎秘密花園經(jīng)典的中文手冊。涵蓋前端知識體系知識結(jié)構(gòu)圖書推薦以及入門視頻教程,全的簡直不要不要的了。 JavaScript 實(shí)現(xiàn)點(diǎn)擊按鈕復(fù)制指定區(qū)域文本 html5 的 webAPI 接口可以很輕松的使用短短的幾行代碼就實(shí)現(xiàn)點(diǎn)擊按鈕復(fù)制區(qū)域文本的功能,不需要依賴 flash。...

    shinezejian 評論0 收藏0
  • 40 行代碼內(nèi)實(shí)現(xiàn)一個(gè) React.js

    摘要:代碼托管這個(gè)倉庫。假設(shè)現(xiàn)在我們需要實(shí)現(xiàn)一個(gè)點(diǎn)贊取消點(diǎn)贊的功能。如果你對前端稍微有一點(diǎn)了解,你就順手拈來點(diǎn)贊為了現(xiàn)實(shí)當(dāng)中的實(shí)際情況,所以這里特易把這個(gè)的結(jié)構(gòu)搞得稍微復(fù)雜一些。這里非常暴力地使用了,把兩個(gè)按鈕粗魯?shù)夭迦肓水?dāng)中。 作者:胡子大哈原文鏈接:http://huziketang.com/blog/posts/detail?postId=58aea515204d50674934c3a...

    twohappy 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<