摘要:無(wú)關(guān)緊要的開(kāi)頭作為一個(gè)年輕的前端從業(yè)者,近期趾高氣昂的去各種面試,抱著找虐心態(tài)去單挑的結(jié)果就是被各種面試題晃斷腳踝并被射,然后開(kāi)始質(zhì)問(wèn)自己對(duì)的掌握為何如此淺薄,為何當(dāng)初不好好學(xué)世界上最好的語(yǔ)言。
/*===無(wú)關(guān)緊要的開(kāi)頭start===*/
作為一個(gè)年輕的前端從業(yè)者,近期趾高氣昂的去各種面試,抱著找虐心態(tài)去單挑的結(jié)果就是被各種面試題晃斷腳踝并被yan射,然后開(kāi)始質(zhì)問(wèn)自己對(duì)js的掌握為何如此淺薄,為何當(dāng)初不好好學(xué)世界上最好的語(yǔ)言php。
當(dāng)然,這不僅提醒了我得背背面試題,還要時(shí)刻謹(jǐn)記,要寫(xiě)安全規(guī)范的javascript代碼
然后小總結(jié)了一下那天面試上來(lái)的就被隔扣的第一題。
/*===無(wú)關(guān)緊要的開(kāi)頭end===*/
null === undefined; // false null == undefined; // true null === 0; // false null == 0; // false false === 0; // false false == 0; // true true === 1; // false true == 1; // true true == "1"; // true true == 2; // false undefined === 0; // false undefined == 0; // false NaN === NaN; // false NaN == NaN; // false !NaN == !NaN; // false !NaN; // true null == NaN; // false !null == !NaN; // true !null === !NaN; // true if(!NaN) console.log("媽呀,這都是啥啊"); // "媽呀,這都是啥啊" false || 0; // 0 !(false || 0) // true true && 1; // 1 true && 2; // 2 !(true && 2) // false !(false || 2) // false let a = 123; let b = new Number(123); a === b; // false a == b; // true let a = document.getElementsByTagName("a"); let b = document.getElementsByTagName("a"); a === b; //true let c = document.querySelectorAll("a"); let d = document.querySelectorAll("a"); c === d; //false /*待續(xù)。。。*/解答
答案在問(wèn)題里邊,真是皮得很...
其實(shí)這些是我根據(jù)當(dāng)時(shí)的面試題整理和擴(kuò)充的,有些代碼中真的是碰不上,但是順手都寫(xiě)上了。其實(shí)有些經(jīng)驗(yàn)的開(kāi)發(fā)者都會(huì)知道這些,小的不才在這再說(shuō)那么一小下。
還有一些ES6中的set和map和symbol等后期會(huì)寫(xiě)到另一篇上。
正經(jīng)解答這道題中涉及到強(qiáng)等、弱等、js中基礎(chǔ)類型轉(zhuǎn)換、懸疑NaN、null和undefined、選擇器等
js中的弱類型造福了人類,到處都是它貼心的幫你各種轉(zhuǎn)換,讓我們的代碼在瀏覽器上、在webview上、在node里、在各種模擬器里、在喜馬拉雅山上、在尼斯湖里、在握不緊的指尖上、在人生的光輝歲月里跑的流暢且難以預(yù)料。
所以:如何安全的寫(xiě)js,其實(shí)真的很重要(忘了這是誰(shuí)說(shuō)的了)。
以下只是我的一些理解,歡迎指正?
1. === 和 == 和類型轉(zhuǎn)換雖然看了一個(gè)很棒的總結(jié)(https://www.cnblogs.com/nelso...)
但是自己的想法還是要講:
‘===’:
(1) 如果是基礎(chǔ)類型進(jìn)行比較,第一件事兒就是比較一下兩邊的數(shù)據(jù)類型,如果不一樣,直接false
(2) 如果兩個(gè)數(shù)據(jù)類型(這里指的還是基礎(chǔ)類型)一樣,那接下來(lái)就是直接的“值”的比較了
(3) 如果是引用類型的變量或者是內(nèi)置函數(shù)構(gòu)造出的變量進(jìn)行比較,那么就是指針的比較了
(4) null和undefined,再?gòu)?qiáng)等面前,只和自己相等。
‘==’:
(1) 如果是基礎(chǔ)類型進(jìn)行比較,類型一樣沒(méi)得說(shuō),類型不一樣,第一件事就是轉(zhuǎn)一下,字符串轉(zhuǎn)數(shù)字再進(jìn)行值的比較,boolean類型轉(zhuǎn)為數(shù)字
這里稍微總結(jié)了一下,可以頑固的認(rèn)為 == 都是再比較數(shù)字,所有的都轉(zhuǎn)換為數(shù)字,然后進(jìn)行“值”的比較了(不知道接下來(lái)這么理解是好還是壞) 舉個(gè)例子:"123" == 123 // true 其實(shí)就是 new Number("123") == 123,兩邊值一樣,那就是true,不一樣就是false; 再舉個(gè)例子: true == 1; //true true == "1" // true true == 2; // false false == 0 // true false == -1 // false 拿true == "1"來(lái)說(shuō) 這樣就是 new Number(true) == new Number("1") 其實(shí)還是兩個(gè)為1的‘值’去比較 (new Number(true)返回一個(gè) Number {1},new Number(false)返回一個(gè) Number {0})
(2)如果是引用類型的變量或者是內(nèi)置函數(shù)構(gòu)造出的變量 和 基礎(chǔ)數(shù)據(jù)類型 去比較,那就是這些變量的值拿出來(lái)去比較,例如 "123asd" == new String("123ads") 返回true
(3)如果是引用類型的變量或者是內(nèi)置函數(shù)構(gòu)造出的變量 相互比較,那還是指針的比較
2. NaNNaN,感覺(jué)其實(shí)就是一個(gè)為了避免非數(shù)字的數(shù)字操作引起程序報(bào)錯(cuò)而設(shè)計(jì)的一個(gè)表示‘Not a Number’的存在,網(wǎng)上有好多好多介紹它的文字
NaN等于誰(shuí)因?yàn)橛懻摰膹?qiáng)等和弱等,那在這只說(shuō)一點(diǎn):NaN和誰(shuí)都不等,不管什么等
所以
———— NaN === NaN 是false
———— NaN==NaN也是false
———— new Number(NaN) == new Number(NaN)也是 false
很難理解為什么是這樣,覺(jué)得是一個(gè)bug,其實(shí)我自己感覺(jué)這樣是對(duì)的,因?yàn)樗褪恰畣渭兊谋硎尽@不是一個(gè)數(shù)字,并沒(méi)有說(shuō)是什么,such as:
NaN + 1; // NaN 那么一個(gè)數(shù)加一還是自己,那自己本來(lái)就不應(yīng)該等于自己。。。 let a = 12/0 //a是NaN let b = 13/0 //b是NaN,但是很簡(jiǎn)單看出a本來(lái)就不應(yīng)該等于b(雖然再高數(shù)上它們是相等的) let raptors = 81/"Kobe" //raptors也是NaN,raptors本來(lái)就不該等于a或者b
所以任何和NaN去比較的話,那都是“不等”!
NaN的判斷那么,該如何判斷是不是NaN呢
不賣(mài)關(guān)子了,我就是來(lái)說(shuō) isNaN 和 Number.isNaN
大家都知道isNaN======>
isNaN不是看上去那個(gè)意思,不是判斷“是一個(gè)NaN”,而是判斷“不是一個(gè)數(shù)字類型的值”,isNaN看上去就是幫你在內(nèi)部把傳入的值進(jìn)行了一次 new Number(param)的操作,然后new Number(param)返回NaN那就判斷為true,但是字符串等類型就沒(méi)有辦法判斷,如下:
isNaN(NaN); // 是個(gè)true isNaN(NaN+1); // 當(dāng)然還是個(gè)true isNaN(123); //當(dāng)然false isNaN("123"); // 幫你轉(zhuǎn)了個(gè)類型,就是內(nèi)部執(zhí)行了一下isNaN(new Number("123")),所以還是false isNaN("Curry"); //返回true,內(nèi)部執(zhí)行了一下(new Number("Curry")返回了NaN
第五行的字符串,竟然被判定為NaN,實(shí)際上它的確不是一個(gè)數(shù)字,但是它的的確確不是我們需要判斷的是一個(gè)NaN,所以這個(gè)方法只是用來(lái)判斷“不是一個(gè)數(shù)字類型的值”
然后大家還知道Number.isNaN======>
es6來(lái)補(bǔ)漏了,Number.isNaN的出現(xiàn)解決了大家希望判斷“是一個(gè)NaN”的操作。如下
Number.isNaN("Curry"); //返回false
NaN結(jié)束了
3. getElement* 和 querySelector*在問(wèn)題中有這樣一個(gè)東西:
let a = document.getElementsByTagName("a"); let b = document.getElementsByTagName("a"); a === b; // true let c = document.querySelectorAll("a"); let d = document.querySelectorAll("a"); c === d; //false
這衍生出來(lái)的:getElementsByTagName查出來(lái)是什么?querySelectorAll查出來(lái)的又是什么?
MDN上告訴我們:
———— getElementsByTagName查出來(lái)的是HTMLCollection,HTMLCollection是一個(gè)動(dòng)態(tài)的dom節(jié)點(diǎn)集合,綁定在document的live上,隨著document變化隨時(shí)更新,指向每一個(gè)符合選擇要求的dom節(jié)點(diǎn),這既是為什么上邊例子中 a===b 為 true 的原因了
———— querySelectorAll查出來(lái)的是NodeList,是一個(gè)單純的選擇器選出的dom節(jié)點(diǎn)集合,這就是為什么上邊例子中 c===d 為 false 了
HTMLCollection和NodeList都是只讀的。jQuery也是使用的querySelectorAll,所以jQuery選擇器選擇出來(lái)也是對(duì)NodeList進(jìn)行操作,所以:
var a = $("a"); var b = $("a"); a === b; // false
所以,事件委托真?zhèn)ゴ?..
總結(jié)其實(shí)由NaN、選擇器、===和==、基本數(shù)據(jù)類型轉(zhuǎn)換、內(nèi)置函數(shù)構(gòu)造出的對(duì)象結(jié)合進(jìn)數(shù)組中,去判斷數(shù)組值相等,去去重、去求交并補(bǔ)等操作,并結(jié)合set和map,都有很多討論的話題,希望下次能分享給大家
感謝各位的閱讀,這些只是我自己的一些理解和想法,希望不正確的地方各位能夠幫忙指正。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/94465.html
摘要:前言新增了兩種基本的原生數(shù)據(jù)集合和加上和現(xiàn)在共有四種,以及由兩者衍生出的弱引用集合和。其本身是生成實(shí)例數(shù)據(jù)集合的構(gòu)造函數(shù),可以接受一個(gè)數(shù)組或具有接口的數(shù)據(jù)結(jié)構(gòu)作為參數(shù)用來(lái)初始化。返回鍵值對(duì)的遍歷器對(duì)象,鍵值對(duì)為鍵名鍵值。 前言 ES6新增了兩種基本的原生數(shù)據(jù)集合:Set和Map(加上Array和Object現(xiàn)在共有四種),以及由兩者衍生出的弱引用集合:WeakSet和WeakMap。從...
摘要:因?yàn)槭褂脝为?dú)的接口存取數(shù)據(jù)所以不用擔(dān)心與內(nèi)置屬性重名修改上面的方法后得到除了以外還有這種數(shù)據(jù)類型這是一個(gè)集合它不允許重復(fù)元素出現(xiàn)。 NaN NaN屬于number,也是一種基本數(shù)據(jù)類型,只要有一邊是 NaN,那么結(jié)果就是false 原始值和包裝對(duì)象 包裝對(duì)象即基本數(shù)據(jù)類型經(jīng)過(guò)包裝之后得到的對(duì)象,作為基本類型值的字符串擁有trim等方法,及l(fā)ength屬性,正是由于JS代碼會(huì)對(duì)原始值做一...
摘要:引用數(shù)據(jù)類型引用數(shù)據(jù)類型值指保存在堆內(nèi)存中的對(duì)象。訪問(wèn)方式是按引用訪問(wèn)。數(shù)據(jù)類型檢測(cè)操作符是檢測(cè)基本類型的最佳工具。未定義布爾值字符串?dāng)?shù)值對(duì)象或函數(shù)用于檢測(cè)引用類型,可以檢測(cè)到它是什么類型的實(shí)例。 前端學(xué)習(xí):教程&開(kāi)發(fā)模塊化/規(guī)范化/工程化/優(yōu)化&工具/調(diào)試&值得關(guān)注的博客/Git&面試-前端資源匯總 歡迎提issues斧正:數(shù)據(jù)類型 回味,無(wú)窮! 數(shù)據(jù)類型定義 數(shù)據(jù)類型分類 基本數(shù)據(jù)...
摘要:作為一個(gè)菜雞的我而言,在之前講到過(guò)那么多的鏈?zhǔn)讲檎覚C(jī)制,比如說(shuō)原型鏈,作用域鏈等等,想當(dāng)然的把這個(gè)機(jī)制帶入到了指向上邊,結(jié)果就是這個(gè)指向指的我萬(wàn)臉懵逼標(biāo)題換字了,擔(dān)心被河蟹在經(jīng)過(guò)漫長(zhǎng)的通俗易懂的規(guī)范閱讀之后,分享一下我所認(rèn)知的指向簡(jiǎn)而言之, 作為一個(gè)js菜雞的我而言,在之前講到過(guò)那么多的js鏈?zhǔn)讲檎覚C(jī)制,比如說(shuō)原型鏈,作用域鏈等等,想當(dāng)然的把這個(gè)機(jī)制帶入到了this指向上邊,結(jié)果就是這...
摘要:中的強(qiáng)制轉(zhuǎn)換規(guī)則面試官中強(qiáng)制類型轉(zhuǎn)換是一個(gè)非常易出現(xiàn)的點(diǎn),知道強(qiáng)制轉(zhuǎn)換時(shí)候的規(guī)則嗎注規(guī)則最好配合下面什么時(shí)候發(fā)生轉(zhuǎn)換使用這些規(guī)則看效果更佳。調(diào)用方法用來(lái)把對(duì)象轉(zhuǎn)換成原始類型的值數(shù)值字符串和布爾值。 前言 showImg(https://segmentfault.com/img/bVbu4Fb?w=940&h=400);之前面試了幾個(gè)開(kāi)發(fā)者,他們確實(shí)做過(guò)不少項(xiàng)目,能力也是不錯(cuò)的,但是發(fā)現(xiàn)...
閱讀 2854·2023-04-25 17:59
閱讀 685·2023-04-25 15:05
閱讀 674·2021-11-25 09:43
閱讀 3036·2021-10-12 10:13
閱讀 3540·2021-09-27 13:59
閱讀 3587·2021-09-23 11:21
閱讀 3884·2021-09-08 09:35
閱讀 569·2019-08-29 17:12