JavaScript 定義了幾種數(shù)據(jù)類(lèi)型? 哪些是原始類(lèi)型?哪些是復(fù)雜類(lèi)型?原始類(lèi)型和復(fù)雜類(lèi)型的區(qū)別是什么?###
JavaScript的數(shù)據(jù)類(lèi)型,共有六種。
- 數(shù)值(number):整數(shù)和小數(shù)(比如1和3.14)
- 字符串(string):字符組成的文本(比如"Hello World")
- 布爾值(boolean):true(真)和false(假)兩個(gè)特定值
- undefined:表示“未定義”或不存在,即此處目前沒(méi)有任何值
- null:表示空缺,即此處應(yīng)該有一個(gè)值,但目前為空
- 對(duì)象(object):各種值組成的集合
通常,我們將數(shù)值、字符串、布爾值稱(chēng)為原始類(lèi)型(primitive type)的值,即它們是最基本的數(shù)據(jù)類(lèi)型,不能再細(xì)分了。而將對(duì)象稱(chēng)為合成類(lèi)型(complex type)的值,因?yàn)橐粋€(gè)對(duì)象往往是多個(gè)原始類(lèi)型的值的合成,可以看作是一個(gè)存放各種值的容器。至于undefined和null,一般將它們看成兩個(gè)特殊值。
基本類(lèi)型變量存的是值,復(fù)雜類(lèi)型的變量存的是內(nèi)存地址。
基本類(lèi)型在賦值的時(shí)候拷貝值,復(fù)雜類(lèi)型在賦值的時(shí)候只拷貝地址,不拷貝值。
typeof和instanceof的作用和區(qū)別?###
- typeof一元運(yùn)算符,用來(lái)返回操作數(shù)類(lèi)型的字符串。
typeof幾乎不可能得到它們想要的結(jié)果。typeof只有一個(gè)實(shí)際應(yīng)用場(chǎng)景,就是用來(lái)檢測(cè)一個(gè)對(duì)象是否已經(jīng)定義或者是否已經(jīng)賦值。而這個(gè)應(yīng)用卻不是來(lái)檢查對(duì)象的類(lèi)型。
在使用 typeof 運(yùn)算符時(shí)采用引用類(lèi)型存儲(chǔ)值會(huì)出現(xiàn)一個(gè)問(wèn)題,無(wú)論引用的是什么類(lèi)型的對(duì)象,它都返回 "object"。
typeof 123
"number"
typeof '123'
"string"
typeof undefined
"undefined"
typeof []
"object"
typeof {}
"object"
typeof null
"object"
- instanceof 運(yùn)算符與 typeof 運(yùn)算符相似,用于識(shí)別正在處理的對(duì)象的類(lèi)型。與 typeof 方法不同的是,instanceof 方法要求開(kāi)發(fā)者明確地確認(rèn)對(duì)象為某特定類(lèi)型。instanceof 是判斷變量是否為某個(gè)對(duì)象的實(shí)例,返回值為true或false
var o = {};
var a = [];
o instanceof Array // false
a instanceof Array // true
如何判斷一個(gè)變量是否是數(shù)字、字符串、布爾、函數(shù)###
使用typeof進(jìn)行基本的數(shù)據(jù)類(lèi)型檢測(cè)
例如:
typeof 123 // "number"
typeof '123' // "string"
typeof undefined // "undefined"
function f() {}
typeof f // "function"
typeof false // "boolean"
NaN是什么? 有什么特別之處?###
- NaN(Not a Number)是一個(gè)特殊的數(shù)值,用于表示一個(gè)本來(lái)要返回?cái)?shù)值的操作數(shù)未被返回的情況。例如,在其它語(yǔ)言中,任何數(shù)值除以非數(shù)值都會(huì)導(dǎo)致錯(cuò)誤,從而停止代碼執(zhí)行,但在ECMAScript中,任何數(shù)值除以非數(shù)值都會(huì)返回NaN,不會(huì)影響其他代碼執(zhí)行。
- NaN本身有兩個(gè)特點(diǎn),首先,任何涉及NaN的操作都會(huì)返回NaN,這個(gè)特點(diǎn)在多步計(jì)算中可能導(dǎo)致問(wèn)題。其次,NaN和任何值都不相等,包括自己。
如何把非數(shù)值轉(zhuǎn)化為數(shù)值?###
Number函數(shù):強(qiáng)制轉(zhuǎn)換成數(shù)值
使用Number函數(shù),可以將任意類(lèi)型的值轉(zhuǎn)化成數(shù)字
1.原始類(lèi)型值的轉(zhuǎn)換規(guī)則
數(shù)值:轉(zhuǎn)換后還是原來(lái)的值。
字符串:如果可以被解析為數(shù)值,則轉(zhuǎn)換為相應(yīng)的數(shù)值,否則得到NaN??兆址D(zhuǎn)為0。
布爾值:true轉(zhuǎn)成1,false轉(zhuǎn)成0。
undefined:轉(zhuǎn)成NaN。
null:轉(zhuǎn)成0。
Number("324") // 324
Number("324abc") // NaN
Number("") // 0
Number(false) // 0
Number(undefined) // NaN
Number(null) // 0
Number函數(shù)將字符串轉(zhuǎn)為數(shù)值,要比parseInt函數(shù)嚴(yán)格很多?;旧希灰幸粋€(gè)字符無(wú)法轉(zhuǎn)成數(shù)值,整個(gè)字符串就會(huì)被轉(zhuǎn)為NaN
parseInt('011') // 9
parseInt('42 cats') // 42
parseInt('0xcafebabe') // 3405691582
Number('011') // 11
Number('42 cats') // NaN
Number('0xcafebabe') // 3405691582
上面代碼比較了Number函數(shù)和parseInt函數(shù),區(qū)別主要在于parseInt逐個(gè)解析字符,而Number函數(shù)整體轉(zhuǎn)換字符串的類(lèi)型。另外,Number會(huì)忽略八進(jìn)制的前導(dǎo)0,而parseInt不會(huì)。
2.對(duì)象的轉(zhuǎn)換規(guī)則
對(duì)象的轉(zhuǎn)換規(guī)則比較復(fù)雜。
先調(diào)用對(duì)象自身的valueOf方法,如果該方法返回原始類(lèi)型的值(數(shù)值、字符串和布爾值),則直接對(duì)該值使用Number方法,不再進(jìn)行后續(xù)步驟。
如果valueOf方法返回復(fù)合類(lèi)型的值,再調(diào)用對(duì)象自身的toString方法,如果toString方法返回原始類(lèi)型的值,則對(duì)該值使用Number方法,不再進(jìn)行后續(xù)步驟。
如果toString方法返回的是復(fù)合類(lèi)型的值,則報(bào)錯(cuò)。
Number({a:1})
// NaN
上面代碼等同于
if (typeof {a:1}.valueOf() === 'object'){
Number({a:1}.toString());
} else {
Number({a:1}.valueOf());
}
上面代碼的valueOf方法返回對(duì)象本身({a:1}),所以對(duì)toString方法的返回值“[object Object]”使用Number方法,得到NaN。
==與===有什么區(qū)別###
== 等于,=== 嚴(yán)格等于。
- ==, 兩邊值類(lèi)型不同的時(shí)候,要先進(jìn)行類(lèi)型轉(zhuǎn)換,再比較
- ===,不做類(lèi)型轉(zhuǎn)換,類(lèi)型不同的一定不等
相等
- 如果兩個(gè)值類(lèi)型相同,則執(zhí)行嚴(yán)格相等的運(yùn)算
- 如果兩個(gè)值的類(lèi)型不同
- 如果一個(gè)是null,一個(gè)是undefined,那么相等
- 如果一個(gè)是數(shù)字,一個(gè)是字符串,先將字符串轉(zhuǎn)為數(shù)字,然后比較
- 如果一個(gè)值是true/false則將其轉(zhuǎn)為1/0比較
- 如果一個(gè)值是對(duì)象,一個(gè)是數(shù)字或字符串,則嘗試使用valueOf和toString轉(zhuǎn)換后比較
- 其它就不相等了,需注意NaN和NaN不等
break與continue有什么區(qū)別###
break關(guān)鍵字在switch語(yǔ)句中已經(jīng)見(jiàn)過(guò),這兩個(gè)關(guān)鍵字多用在循環(huán)語(yǔ)句中
- break 用于強(qiáng)制退出循環(huán)體,執(zhí)行循環(huán)后面的語(yǔ)句
- continue 用于退出本次循環(huán),執(zhí)行下次循環(huán)
看個(gè)例子對(duì)比一下
for(var i = 1; i< 10; i++){
if(i % 4 === 0){
break; //輸出結(jié)果為1,2,3
}
console.log(i);
}
for(var i = 1; i< 10; i++){
if(i % 4 === 0){
continue; //輸出結(jié)果為1,2,3,5,6,7,9
}
console.log(i);
}
void 0 和 undefined在使用場(chǎng)景上有什么區(qū)別###
void運(yùn)算符的作用是執(zhí)行一個(gè)表達(dá)式,然后不返回任何值,或者說(shuō)返回undefined。
undefined 可能會(huì)被重寫(xiě),但是 void 0 返回的值一定會(huì)是 undefined。其中有一個(gè)作用,是點(diǎn)擊網(wǎng)頁(yè)鏈接時(shí)頁(yè)面不發(fā)生跳轉(zhuǎn),
<a href="javascript:void(0)>"
在 href="javascript:void(0)" 中,使用了一個(gè)以 javascript: 協(xié)議開(kāi)頭的 URI,瀏覽器默認(rèn)會(huì)對(duì)冒號(hào)后面的代碼求值,然后將結(jié)果顯示在新的頁(yè)面,但有一種情況例外,如果結(jié)果是 undefined,瀏覽器就不會(huì)刷新頁(yè)面渲染新值了。
9.以下代碼的輸出結(jié)果是?為什么?
console.log(1+1); // 2 兩個(gè)數(shù)字加法
console.log("2"+"4"); //'24' 兩個(gè)字符串相加直接拼接
console.log(2+"4"); // '24' 一個(gè)數(shù)字與一個(gè)字符串相加,把數(shù)字轉(zhuǎn)換成字符串,做拼接
console.log(+"4"); // 4 這是數(shù)值運(yùn)算符,會(huì)把字符串轉(zhuǎn)換成數(shù)字
10.以下代碼的輸出結(jié)果是?
var a = 1;
a+++a; // 3 相當(dāng)于(a++)+a a++是先運(yùn)算后賦值 相當(dāng)于1+2
typeof a+2; // 輸出"number2" 因?yàn)閠ypeof優(yōu)先級(jí)大于+,typeof a 的結(jié)果"number"是一個(gè)字符串 應(yīng)該與2做拼接
11. 以下代碼的輸出結(jié)果是? 為什么
var a = 1;
var b = 3;
console.log( a+++b );// 輸出結(jié)果是4 相當(dāng)于是(a++)+b, a++ 為1,1+3為4
12. 遍歷數(shù)組,把數(shù)組里的打印數(shù)組每一項(xiàng)的平方
var arr = [3,4,5];
for(var i=0;i<arr.length;i++){
console.log(arr[ i ]*arr[ i ]);
}
13. 遍歷 JSON, 打印里面的值
var obj = {
name: 'hunger',
sex: 'male',
age: 28
}
for(var key in obj){
console.log(key+":"+obj[key])
}
輸出結(jié)果是什么?為什么
- 且運(yùn)算符的運(yùn)算規(guī)則是:如果第一個(gè)運(yùn)算子的布爾值為true,則返回第二個(gè)運(yùn)算子的值(注意是值,不是布爾值);如果第一個(gè)運(yùn)算子的布爾值為false,則直接返回第一個(gè)運(yùn)算子的值,且不再對(duì)第二個(gè)運(yùn)算子求值。
- 或運(yùn)算符(||)的運(yùn)算規(guī)則是:如果第一個(gè)運(yùn)算子的布爾值為true,則返回第一個(gè)運(yùn)算子的值,且不再對(duì)第二個(gè)運(yùn)算子求值;如果第一個(gè)運(yùn)算子的布爾值為false,則返回第二個(gè)運(yùn)算子的值。
- 逗號(hào)運(yùn)算符用于對(duì)兩個(gè)表達(dá)式求值,并返回后一個(gè)表達(dá)式的值。
var a = 1, b = 2, c = 3;
var val = typeof a + b || c >0
console.log(val) // 輸出number2 , (typeof a)+b輸出的'number2' 轉(zhuǎn)換成數(shù)值是number2 左側(cè)的布爾值為true, 直接輸出左側(cè)值
var d = 5;
var data = d ==5 && console.log('bb')
console.log(data) // d==5為true,返回bb
var data2 = d = 0 || console.log('haha')
console.log(data2) //0轉(zhuǎn)換為布爾類(lèi)型為false ||左為false 輸出右側(cè)的值
var x = !!"Hello" + (!"world", !!"from here!!");
console.log(x) //輸出2 , 相當(dāng)于true+(false,true)