JavaScript 定義了幾種數(shù)據(jù)類型? 哪些是原始類型?哪些是復(fù)雜類型?原始類型和復(fù)雜類型的區(qū)別是什么?###
JavaScript的數(shù)據(jù)類型棕诵,共有六種嘱支。
- 數(shù)值(number):整數(shù)和小數(shù)(比如1和3.14)
- 字符串(string):字符組成的文本(比如"Hello World")
- 布爾值(boolean):true(真)和false(假)兩個(gè)特定值
- undefined:表示“未定義”或不存在,即此處目前沒(méi)有任何值
- null:表示空缺憎妙,即此處應(yīng)該有一個(gè)值搂擦,但目前為空
- 對(duì)象(object):各種值組成的集合
通常雳灵,我們將數(shù)值、字符串糊肠、布爾值稱為原始類型(primitive type)的值辨宠,即它們是最基本的數(shù)據(jù)類型,不能再細(xì)分了货裹。而將對(duì)象稱為合成類型(complex type)的值嗤形,因?yàn)橐粋€(gè)對(duì)象往往是多個(gè)原始類型的值的合成,可以看作是一個(gè)存放各種值的容器弧圆。至于undefined和null赋兵,一般將它們看成兩個(gè)特殊值。
基本類型變量存的是值搔预,復(fù)雜類型的變量存的是內(nèi)存地址霹期。
基本類型在賦值的時(shí)候拷貝值,復(fù)雜類型在賦值的時(shí)候只拷貝地址拯田,不拷貝值历造。
typeof和instanceof的作用和區(qū)別?###
- typeof一元運(yùn)算符,用來(lái)返回操作數(shù)類型的字符串。
typeof幾乎不可能得到它們想要的結(jié)果吭产。typeof只有一個(gè)實(shí)際應(yīng)用場(chǎng)景侣监,就是用來(lái)檢測(cè)一個(gè)對(duì)象是否已經(jīng)定義或者是否已經(jīng)賦值。而這個(gè)應(yīng)用卻不是來(lái)檢查對(duì)象的類型臣淤。
在使用 typeof 運(yùn)算符時(shí)采用引用類型存儲(chǔ)值會(huì)出現(xiàn)一個(gè)問(wèn)題橄霉,無(wú)論引用的是什么類型的對(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ì)象的類型。與 typeof 方法不同的是寺董,instanceof 方法要求開發(fā)者明確地確認(rèn)對(duì)象為某特定類型覆糟。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ù)類型檢測(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ù)碟联,可以將任意類型的值轉(zhuǎn)化成數(shù)字
1.原始類型值的轉(zhuǎn)換規(guī)則
數(shù)值:轉(zhuǎn)換后還是原來(lái)的值妓美。
字符串:如果可以被解析為數(shù)值,則轉(zhuǎn)換為相應(yīng)的數(shù)值鲤孵,否則得到NaN部脚。空字符串轉(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)換字符串的類型。另外戳吝,Number會(huì)忽略八進(jìn)制的前導(dǎo)0浩销,而parseInt不會(huì)。
2.對(duì)象的轉(zhuǎn)換規(guī)則
對(duì)象的轉(zhuǎn)換規(guī)則比較復(fù)雜听哭。
先調(diào)用對(duì)象自身的valueOf方法慢洋,如果該方法返回原始類型的值(數(shù)值、字符串和布爾值)陆盘,則直接對(duì)該值使用Number方法普筹,不再進(jìn)行后續(xù)步驟。
如果valueOf方法返回復(fù)合類型的值隘马,再調(diào)用對(duì)象自身的toString方法太防,如果toString方法返回原始類型的值,則對(duì)該值使用Number方法酸员,不再進(jìn)行后續(xù)步驟杏头。
如果toString方法返回的是復(fù)合類型的值,則報(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)格等于叛氨。
- ==呼渣, 兩邊值類型不同的時(shí)候,要先進(jìn)行類型轉(zhuǎn)換寞埠,再比較
- ===屁置,不做類型轉(zhuǎn)換,類型不同的一定不等
相等
- 如果兩個(gè)值類型相同仁连,則執(zhí)行嚴(yán)格相等的運(yùn)算
- 如果兩個(gè)值的類型不同
- 如果一個(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ì)被重寫,但是 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é)議開頭的 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)換為布爾類型為false ||左為false 輸出右側(cè)的值
var x = !!"Hello" + (!"world", !!"from here!!");
console.log(x) //輸出2 , 相當(dāng)于true+(false,true)