進(jìn)階2: 數(shù)據(jù)類型運(yùn)算符流程控制語(yǔ)句

1. JavaScript 定義了幾種數(shù)據(jù)類型? 哪些是原始類型?哪些是復(fù)雜類型?原始類型和復(fù)雜類型的區(qū)別是什么?

JavaScript 語(yǔ)言的每一個(gè)值,都屬于某一種數(shù)據(jù)類型西土。JavaScript 的數(shù)據(jù)類型,共有六種啤斗。(ES6 又新增了第七種 Symbol 類型的值)分別為:

數(shù)值(number)
字符串(string)
布爾值(boolean)
undefined
null
對(duì)象(object)
數(shù)值乐横、字符串、布爾值稱為原始類型(primitive type)的值
對(duì)象稱為合成類型(復(fù)雜類型)(complex type)的值
undefined 和 null 一般看成兩個(gè)特殊值


2. typeof和instanceof的作用和區(qū)別?

  • typeof可以檢測(cè)給定變量的數(shù)據(jù)類型娘锁,但是有局限性牙寞,對(duì)于Array、Null等特殊對(duì)象使用typeof一律返回object莫秆。 此外间雀,typeof可以用來判斷一個(gè)變量是否存在,或者是未被定義 if (typeof v === "undefined") {
  • 既然typeof對(duì)數(shù)組(array)和對(duì)象(object)的顯示結(jié)果都是object镊屎,那么就需要 instanceof(非唯一方法) 進(jìn)行區(qū)分惹挟。
    instanceof用于判斷一個(gè)變量是否某個(gè)對(duì)象的實(shí)例,比如 var a = []; 那么 a instanceof Array 就會(huì)返回true缝驳。

3. 如何判斷一個(gè)變量是否是數(shù)字连锯、字符串、布爾用狱、函數(shù)

使用typeof, 能返回字符串运怖,里面告訴了什么類型,未定義夏伊、 數(shù)字摇展、字符串、布爾署海、函數(shù)吗购、分別對(duì)應(yīng)医男,"undefined"、"number"捻勉、"string"镀梭、"boolean"、"function"踱启。


4. NaN是什么? 有什么特別之處?

NaN含義是Not a Number报账,即非數(shù)值,是一個(gè)特殊的數(shù)值埠偿,用于表示一個(gè)本來要返回?cái)?shù)值的操作數(shù)未返回?cái)?shù)值的情況(這樣就不會(huì)拋出錯(cuò)誤了)透罢。

特殊之處:

  • 任何涉及NaN的操作(例如NaN+10)都會(huì)返回NaN
  • NaN和任何值都不相等,包括NaN本身(例如 NaN == NaN //false)

5. 如何把非數(shù)值轉(zhuǎn)化為數(shù)值?

有三個(gè)函數(shù)可以把非數(shù)值轉(zhuǎn)換為數(shù)值

1. Number()
2. parseInt()
3. parseFloat()

Number()

  • Number()可以用于任何數(shù)據(jù)類型冠蒋,布爾值 true=>1, false=>0. 數(shù)字則是簡(jiǎn)單傳入羽圃,null=>0, undefined=>NaN,
  • 字符串
    • 字符串只包含數(shù)字(十進(jìn)制、八進(jìn)制抖剿、十六進(jìn)制)都會(huì)轉(zhuǎn)換成十進(jìn)制朽寞;
    • 字符串包含有效的浮點(diǎn)格式,則轉(zhuǎn)換為對(duì)應(yīng)的浮點(diǎn)數(shù)值斩郎;
    • 字符串是空的(包括空格字符)脑融,都轉(zhuǎn)換為0;
    • 如果字符串包含除上述格式之外的字符缩宜,則將其轉(zhuǎn)換為NaN, 這意味著需要parseInt() 和 parseFloat() 進(jìn)一步對(duì)字符串進(jìn)行更合理的轉(zhuǎn)換肘迎。
  • 如果是對(duì)象,則調(diào)用對(duì)象的valueOf()方法锻煌,然后依照前面的規(guī)則轉(zhuǎn)換返回的值妓布。如果轉(zhuǎn)換結(jié)果是NaN,則繼續(xù)調(diào)用對(duì)象的 toString() 方法宋梧,然后再次依照規(guī)則轉(zhuǎn)換返回的字符串值秋茫。

parseInt() 和parseFloat()

  • 都是對(duì)字符串進(jìn)行數(shù)制轉(zhuǎn)換。前者是針對(duì)整數(shù)格式乃秀,后者是解析包括整數(shù)在內(nèi)的浮點(diǎn)格式的數(shù)值。
  • parseInt()可以指定第二個(gè)參數(shù)作為轉(zhuǎn)換時(shí)的基數(shù)圆兵,指定有多少進(jìn)制進(jìn)行轉(zhuǎn)化跺讯,比如parseInt(111,2) 結(jié)果是7,如果不指定parseInt(111), 則默認(rèn)是十進(jìn)制進(jìn)行解析轉(zhuǎn)換殉农,那么結(jié)果就是111刀脏,除了指定二進(jìn)制,你還可以指定其他進(jìn)制超凳。
    因此多數(shù)情況下愈污,我們要解析的都是十進(jìn)制數(shù)值耀态,因此還是建議指定10,避免錯(cuò)誤解析暂雹。
  • 相同點(diǎn)
    • 忽略字符串前面的空白字符首装,找到第一個(gè)非空白字符
    • 如果第一個(gè)字符不是-或者數(shù)字返回NaN
    • 0開頭會(huì)當(dāng)做八進(jìn)制,0x開頭會(huì)當(dāng)做十六進(jìn)制
    • 如果是繼續(xù)解析杭跪,直到非數(shù)值模式為止
    • 如果是空字符串(包括含有空格的字符串)仙逻,則返回NaN

6. ==與===有什么區(qū)別

首先,二者都是比較運(yùn)算符涧尿。用來比較兩個(gè)值系奉,然后返回布爾值,用true 或者 false 來表示是否滿足比較條件姑廉。
但是缺亮, ==表示相等 , === 表示嚴(yán)格相等桥言。
例如:

5 == '5' 

使用相等比較運(yùn)算符的時(shí)候萌踱,會(huì)將string '5',自動(dòng)轉(zhuǎn)換成number 5限书,進(jìn)行比較虫蝶,從而可以滿足比較條件,因?yàn)?5 == 5倦西。

但是 :

5 === '5' 

使用 === 嚴(yán)格相等 的比較運(yùn)算符時(shí)能真, 則不會(huì)自動(dòng)做轉(zhuǎn)換處理,顯然 number 5 扰柠,是不會(huì)和 string '5',相等的粉铐。因此,返回boolean的 false值卤档。


7. break與continue有什么區(qū)別

break用于強(qiáng)制退出循環(huán)體蝙泼,執(zhí)行循環(huán)后面的語(yǔ)句,
比如:

for( var i = 1; i < 5; i++ ){
  if( i === 3 ){
    break;
  }
  console.log(i);
}
// 輸出為 1 2
// break 為強(qiáng)制退出整個(gè)循環(huán)體劝枣,執(zhí)行后面的語(yǔ)句所以輸出 1  2 到此為止 
for( var i = 1; i < 5; i++ ){
  if( i === 3 ){
    continue;
  }
  console.log(i);
}
// 輸出為 1 2 4
// continue 用于退出本次循環(huán)汤踏,執(zhí)行下次循環(huán)
//所以 i === 3的時(shí)候,這一次退出循環(huán)舔腾,不再輸出 i溪胶,但是此后 繼續(xù) i++,進(jìn)行下一次的 i < 5 的判斷

8. void 0 和 undefined 在使用場(chǎng)景上有什么區(qū)別

先看一個(gè)例子:

function fn() {
  var undefined = 3;
  var a;
  if(a === undefined ){
    console.log('===') 
  }else{
    console.log('!==')
  }
}
fn()

上面的代碼中稳诚,a雖然聲明變量了哗脖,但是沒有賦值常空,所以應(yīng)該是未定義undefined家破,在接下來的條件判斷語(yǔ)句中琳省,a應(yīng)該會(huì)嚴(yán)格等于undefined哺壶。
但是在一開始,對(duì) undefined 聲明并且賦值為3
Infinity桑逝、NaN棘劣、undefined 這三個(gè)詞雖然不是保留字,但因?yàn)榫哂刑貏e含義肢娘,一般不應(yīng)該用作標(biāo)識(shí)符呈础,但是強(qiáng)行用也是可以的。
這個(gè)時(shí)候橱健,程序的結(jié)果是 !==, 顯然a !== undefined而钞,嚴(yán)格不等于undefined,因?yàn)閡ndefined是3拘荡, 實(shí)際上臼节,a != undefined ,a 也不等于 undefined珊皿,徹底的不一樣了网缝。

然而,a顯然還是undefined蟋定,未定義粉臊。這是個(gè)bug,怎么辦呢驶兜?所以要最保險(xiǎn)的方法是是void操作符扼仲。
void運(yùn)算符的作用是執(zhí)行一個(gè)表達(dá)式,然后返回undefined抄淑。
根據(jù)這個(gè)特性屠凶,其他不變,把if判斷條件修改一下:

function fn() {
  var undefined = 3;
  var a;
  if(a === void 0 ){
    console.log('===') 
  }else{
    console.log('!==')
    console.log(a)
  }
}
fn()

此時(shí) void 優(yōu)先級(jí)高于 比較運(yùn)算符 === 肆资,所以 void 0 無(wú)腦返回 undefined矗愧,從而 a === 真正純天然無(wú)污染的 undefined。最后判斷結(jié)果是 布爾值 true郑原。 輸出 ===


9. 以下代碼的輸出結(jié)果是?為什么?

console.log(1+1);   //輸出number 2
console.log("2"+"4");  //輸出string "24"
console.log(2+"4");  //輸出string "24"
console.log(+"4");  //輸出number 4

下面解釋一下原因:

首先這些都是 運(yùn)算符 + 在不同數(shù)據(jù)類型下具有的不同含義唉韭。

  1. 第一個(gè)很好理解,兩個(gè)參數(shù)都是數(shù)字犯犁,則此時(shí)的+就是加法運(yùn)算纽哥。
  2. 兩個(gè)參數(shù)都是string,這時(shí)候會(huì)進(jìn)行字符串的拼接栖秕,于是拼接成新的string "24"。
  3. 一個(gè)參數(shù)是number晓避,但是另一個(gè)是string簇捍,那么會(huì)把number轉(zhuǎn)化成string只壳,與另一個(gè)string進(jìn)行拼接。所以結(jié)果還是string '24'暑塑。
  4. 最后一個(gè)吼句,只有一個(gè)數(shù)字參數(shù),則會(huì)返回其正整數(shù)事格。是number惕艳,直接返回number,是string驹愚,但里面是number远搪,則還是返回number,如果 console.log("jirengu")逢捺,則返回NaN谁鳍。可以理解為 本性還是數(shù)值類型劫瞳,但是字符串 jirengu倘潜,是沒辦法轉(zhuǎn)化成一個(gè)具體number值的。

10. 以下代碼的輸出結(jié)果是?

var a = 1;  
a+++a;  
typeof a+2;

結(jié)果是字符串 "number2"
為什么會(huì)這樣子志于?
因?yàn)檫@里的 + 實(shí)際上并不是算數(shù)運(yùn)算符里面的加法運(yùn)算符涮因,而是代表字符串拼接。
a 不管怎樣伺绽,都是number類型养泡,而typeof返回的是數(shù)據(jù)類型是string格式的(注意,這里不是說typeof返回的結(jié)果憔恳,告訴我們是string類型瓤荔。)
至于第二行中 a+++a,實(shí)際上可以拆分成:
(a++)(+a)
理解為:
a=1
b=a
a= a+1
b+a


11. 以下代碼的輸出結(jié)果是? 為什么

 var a = 1;
 var b = 3;
 console.log( a+++b ); //輸出結(jié)果是4

結(jié)果是4钥组, 首先++ 自增運(yùn)算符優(yōu)先級(jí)高于 + 加法運(yùn)算符输硝。 a++,表示參與當(dāng)前的運(yùn)算后(先賦值)程梦,再自增1点把。
所以是 1 + 3 = 4
這時(shí)候,再console.log(a) , 則返回 2


12. 遍歷數(shù)組屿附,打印數(shù)組每一項(xiàng)的平方

var arr = [3, 4, 5]
for(i = 0; i<arr.length; i++){
  console.log(arr[i]*arr[i])
} 
// 輸出為 9 16 25

倒序遍歷數(shù)組并打印

 var arr = [100, 90, 80, 70, 60]
 for(var i = arr.length - 1; i >= 0; i-- ){
   console.log(arr[i])
 }
// 輸出為 60 70 80 90 100

正序遍歷偶數(shù)序位的數(shù)組

var arr = [100, 90, 80, 70, 60, 50, 40]
for(var i = 1; i < arr.length; i += 2){
  console.log(arr[i])
}
// 輸出為 90 70 50

13. 遍歷 JSON, 打印里面的值

var obj = {
 name: 'hunger', 
 sex: 'male', 
 age: 28 
}
for( var key in obj ){
  console.log(obj[key])
}
// 輸出為 hunger male 28

14. 以下代碼輸出結(jié)果是? 為什么 (選做題目)

var a = 1, b = 2, c = 3; 
var val = typeof a + b || c >0
console.log(val) 
// 輸出 number2

typeof優(yōu)先級(jí)最高郎逃,判斷a是"number",接著和 2 進(jìn)行拼接挺份,成為"number2"褒翰,由于是 || 或運(yùn)算符,所以左邊成立,右邊即可忽略优训,不會(huì)執(zhí)行朵你。 因此最后把"number" 賦值給 val,通過console.log(val) 的時(shí)候揣非,就去掉了""

var d = 5;
var data = d ==5 && console.log('bb')
console.log(data)
// 輸出 bb undefined

因?yàn)橄葓?zhí)行console.log 輸出bb抡医,然后 d == 5為 true,然后&&右邊 console.log('bb') 無(wú)法被自動(dòng)轉(zhuǎn)換為布爾值早敬,不是true也不是false忌傻,而是undefined,于是就把undefined 賦值給了 data搞监。

var data2 = d = 0 || console.log('haha')
console.log(data2)
// 輸出 haha  defined

首先因?yàn)槭莄onsole.log所以先無(wú)腦輸出haha水孩, 然后 因?yàn)檫@是或運(yùn)算符,左邊 0 轉(zhuǎn)化為false腺逛,所以繼續(xù)看右邊的荷愕,右邊console.log('haha')無(wú)法被有效的轉(zhuǎn)換為 布爾值boolean, 因此是undefined未定義棍矛。所以最后把 undefined賦值給 data2安疗。
所以最后輸出兩行:
haha
defined
因?yàn)閏onsole.log()方法會(huì)自動(dòng)換行

var x = !!"Hello" + (!"world", !!"from here!!");
console.log(x)
// 輸出 2

原因很簡(jiǎn)單, 首先括號(hào)優(yōu)先級(jí)最高够委,其次里面有逗號(hào)運(yùn)算符荐类,雖然逗號(hào)運(yùn)算符低的不要不要的, 但是可以讓我們?nèi)ズ雎远禾?hào)前面的 !"world"
所以返回的是逗號(hào)后面的表達(dá)式茁帽, "from here!!" 本來是無(wú)辜的字符串玉罐,但是使用了布爾運(yùn)算符中的 ! 取反運(yùn)算符,所以被偷偷轉(zhuǎn)換為布爾值潘拨,因?yàn)樽址强盏跏洌允莟rue,進(jìn)行了兩次取反铁追,最后還是true季蚂。
然后再看!!"Hello" 同理,轉(zhuǎn)換為boolean值 true琅束, 這時(shí)候 有個(gè) 加法運(yùn)算符 + 扭屁,
于是布爾值 又被偷偷轉(zhuǎn)換為number參與 加法運(yùn)算, true對(duì)應(yīng)的是1涩禀,
所以料滥,大聲告訴我:
x = 1 + 1
請(qǐng)問 x 是多少?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末艾船,一起剝皮案震驚了整個(gè)濱河市葵腹,隨后出現(xiàn)的幾起案子高每,更是在濱河造成了極大的恐慌,老刑警劉巖礁蔗,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件觉义,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡浴井,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門霉撵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來磺浙,“玉大人,你說我怎么就攤上這事徒坡∷貉酰” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵喇完,是天一觀的道長(zhǎng)伦泥。 經(jīng)常有香客問我,道長(zhǎng)锦溪,這世上最難降的妖魔是什么不脯? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮刻诊,結(jié)果婚禮上防楷,老公的妹妹穿的比我還像新娘。我一直安慰自己则涯,他們只是感情好复局,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著粟判,像睡著了一般亿昏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上档礁,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天角钩,我揣著相機(jī)與錄音,去河邊找鬼事秀。 笑死彤断,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的易迹。 我是一名探鬼主播宰衙,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼睹欲!你這毒婦竟也來了供炼?” 一聲冷哼從身側(cè)響起一屋,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎袋哼,沒想到半個(gè)月后冀墨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡涛贯,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年诽嘉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片弟翘。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡虫腋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出稀余,到底是詐尸還是另有隱情悦冀,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布睛琳,位于F島的核電站盒蟆,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏师骗。R本人自食惡果不足惜历等,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望丧凤。 院中可真熱鬧募闲,春花似錦、人聲如沸愿待。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)仍侥。三九已至要出,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間农渊,已是汗流浹背患蹂。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留砸紊,地道東北人传于。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像醉顽,于是被迫代替她去往敵國(guó)和親沼溜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容