js數(shù)據(jù)類型
js定義了6種數(shù)據(jù)類型,數(shù)值、字符串、布爾值稱為原始數(shù)據(jù)類型的值即基本數(shù)據(jù)類型。
將對(duì)象稱為復(fù)雜類型的值,對(duì)象又可以細(xì)分為狹義的對(duì)象、數(shù)組、函數(shù)、正則表達(dá)式。因?yàn)橐粋€(gè)對(duì)象往往是多個(gè)原始類型的值的合成,可以看做是一個(gè)存放各種值的容器。
至于undefined和null,一般將他們看成兩個(gè)特殊值。
數(shù)值(number):整數(shù)和小數(shù)
字符串(string):字符組成的文本
布爾值(boolean):true和false
undefined:未定義或不存在,即此處目前沒有任何值。
null: 空缺,即此處應(yīng)該有一個(gè)值但目前為空
對(duì)象: 各種值組成的集合。
基本數(shù)據(jù)類型和引用類型的區(qū)別:
基本數(shù)據(jù)類型
- 基本數(shù)據(jù)類型的值是不可變的
var name="hello";
name.substr(2);//此處sunstr方法返回新的字符串
console.log(name);//"hello"
- 基本數(shù)據(jù)類型不可以添加屬性和方法
- 基本數(shù)據(jù)類型是簡單的賦值
- 基本數(shù)據(jù)類型是值的比較
var a="{}";
var b="{}";
console.log(a==b);//這里是字符串的比較,所以返回的是true。
- 基本數(shù)據(jù)類型存放在棧中,棧里存放的是一個(gè)字典,左側(cè)是key(變量名),右側(cè)是value(真正的值)
引用類型 - 值是可以改變的
var o={x:1};
o.x=2;//console.log(o.x)已經(jīng)變成2了。
- 可以添加屬性和方法
- 引用類型賦值的是對(duì)象的引用
var a={};
var b=a;//b在棧中新建了一個(gè)地址,指向了a在堆中存儲(chǔ)的數(shù)據(jù)
a.name="change";//a的更改影響b的數(shù)值
console.log(a.name);//change
console.log(b.name);//change
- 引用類型比較的是引用地址
var a={};
var b={};
console.log(a==b);//這里返回的是false。
- 引用類型數(shù)據(jù)會(huì)保存在棧和堆中
var a={name:"zs"}
棧中保存的是a和一個(gè)分配的地址,堆中保存的是'{name:"zs"}'
typeof和instanceof的作用和區(qū)別
typeof 用以獲取一個(gè)變量的類型,typeof一般只能返回如下幾個(gè)結(jié)果: number ,boolean ,string, function, object, undefined,我們可以使用typeof來獲取一個(gè)變量是否存在,如if(typeof a!="undefined"){}
,而不用去使用if(a)因?yàn)槿绻鸻 不存在(未聲明)就會(huì)出錯(cuò),對(duì)于Array,Null等特殊對(duì)象使用typeof一律返回object,這正是typeof的局限性。
如果我們希望獲取一個(gè)對(duì)象是否是數(shù)組,或判斷某個(gè)變量是否是某個(gè)對(duì)象的實(shí)例則要選擇使用instanceof。instanceof用于判斷一個(gè)變量是否是某個(gè)對(duì)象的實(shí)例,例如var a=new Array();alert (a instanceof Array);
會(huì)返回true;同時(shí)alert(a instanceof object)
也會(huì)返回true,這是因?yàn)锳rray是object的子類。再如function test (){};var new test();alert(a instanceof test)
會(huì)返回true。
判斷一個(gè)變量是否是數(shù)字、字符串、布爾、函數(shù)
typeof
typeof返回6種數(shù)據(jù)類型,但是對(duì)于所有的對(duì)象都返回object,不能返回自定義的數(shù)據(jù)類型。比如,date,regexp,array,domelement的類型都是object,另外,typeof null是object。
instanceof
instanceof適用于任何object類型的檢查。
function animal(){
(new animal) instanceof animal //直接原型關(guān)系返回true
}
function cat(){}
cat.prototype=new animal
(new cat) instanceof animal // 原型鏈上的間接原型
instanceof也可以用于檢測實(shí)例比如 array, regexp,object, function。這一點(diǎn)可以區(qū)分?jǐn)?shù)組和對(duì)象
[1,2,3]instanceof array //true
/abc/ instanceof RegExp //true
var o={};
var a=[];
o instanceof Array//false,o不是Array的實(shí)例
a instanceof Array//true,instanceof判斷是否是數(shù)組實(shí)例
instanceof 對(duì)基本數(shù)據(jù)類型不起作用,但是可以這樣:
new Number(3) instanceof Number // true
但這時(shí)你已經(jīng)知道數(shù)據(jù)類型了,類型檢查已經(jīng)沒有用了。
toString
toString方法是最為可靠的類型檢測手段,它會(huì)將當(dāng)前的對(duì)象轉(zhuǎn)為字符并輸出。toString屬性定義在object.prototype上。因而所有的對(duì)象都有toString
方法。但array,date等對(duì)象會(huì)重寫object.prototype繼承來的toString,所以最好用Object.protoytpe.toString來檢測類型。
toString=Object.prototype.toString;
toString.call(3)//[Object Number]
toString適用于ecma的內(nèi)置js類型(包括基本數(shù)據(jù)類型和對(duì)象)但是不能判斷自定義的數(shù)據(jù)類型。
NaN
即非數(shù)值是一個(gè)特殊的數(shù)值。
parseInt('abc')//NaN
任何數(shù)值除以非數(shù)值會(huì)返回NaN;
任何涉及NaN的操作都會(huì)返回NaN;
NaN與任何值都不相等,包括NaN本身。
非數(shù)值轉(zhuǎn)化為數(shù)值
- number()函數(shù),不常用
- paseInt()
轉(zhuǎn)換規(guī)律
- 忽略字符串前面的空白字符,找到第一個(gè)非空白字符
- 如果第一個(gè)字符不是-或者數(shù)字則返回NaN
- 如果是,繼續(xù)解析,直到非數(shù)值模式為止
- 0開頭會(huì)當(dāng)做八進(jìn)制,0X開頭會(huì)當(dāng)做十六進(jìn)制,可以指定第二個(gè)參數(shù)指定基數(shù)
parseInt('101' ,2)
,其中2就是二進(jìn)制。
- paseFloat()
paseFloat('3.4')//3.4
布爾類型
==與===的區(qū)別
==是近似相等,使用==的時(shí)候,js會(huì)幫助我們做類型的轉(zhuǎn)化然后再比較值,造成一些匪夷所思的結(jié)果,那么使用==的時(shí)候會(huì)在哪些情況下做類型的轉(zhuǎn)換,又會(huì)轉(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)換后比較。
- 其他的就不相等了。
===是絕對(duì)相等:數(shù)據(jù)類型一樣再比較值,用此做判斷最嚴(yán)謹(jǐn)。
轉(zhuǎn)換為false的類型
如果js預(yù)期某個(gè)位置應(yīng)該是布爾值,會(huì)將該位置上現(xiàn)有的值自動(dòng)轉(zhuǎn)為布爾值,轉(zhuǎn)換規(guī)則是除了下面六個(gè)值被轉(zhuǎn)換為false其他值都視為true。undefined,null,false,0,nan,""(不能為空格,空字符串)
if(undefined){console.log('ok')}//undefined
if(!undefined){console.log('ok')}//ok
空對(duì)象和空數(shù)組的轉(zhuǎn)換
[]和{}對(duì)應(yīng)的布爾值都是true。
Number
js的數(shù)字類型和其他語言有所 不同,沒有整型和浮點(diǎn)數(shù)的區(qū)別,統(tǒng)一都是Number,可以表示十進(jìn)制、八進(jìn)制、十六進(jìn)制。
浮點(diǎn)數(shù)
浮點(diǎn)數(shù)是指數(shù)字包含小數(shù)點(diǎn)、小數(shù)點(diǎn)后至少有一位數(shù)字(沒有或是會(huì)轉(zhuǎn)換 為整數(shù)),前面可以沒有。
var a=3.1e5
var b=.45
對(duì)于極大或者極小的數(shù)字可以使用科學(xué)計(jì)數(shù)法
var a=3.1e5//310000
浮點(diǎn)數(shù)最高精度是17位,但在計(jì)算的時(shí)候精度不如整數(shù)所以在做小數(shù)運(yùn)算時(shí)不要做判斷
1-0.9;//0.099999...8
a=0.1,b=0.2
if(a+b==='0.3'){
console.log('ok')//undefined
}
整數(shù)有最大值、最小值限制,當(dāng)超過范圍后就不精確了。
Infinity表示無窮大,也是number類型。1/0。
string
可以用單引號(hào)或者雙引號(hào)表示。
object
對(duì)象就是一種無序的數(shù)據(jù)集合,由若干個(gè) ‘鍵值對(duì)’(key-value)構(gòu)成,key我們通常稱為對(duì)象的屬性,value可以是任何js類型,甚至可以是對(duì)象。
屬性的讀取
object的屬性讀取有兩種方式
obj.name
obj['name']
null和undefined
null和undefined都可以表示“沒有”,含義非常相似,將一個(gè)變量賦值為‘undefined’和null的效果非常相似。
var a=undefined//直接寫var hello打印hello就會(huì)出現(xiàn)undefined
var a=null//但是對(duì)于null必須賦值為null,var world=null,打印world
在if語句中,它們都會(huì)被自動(dòng)轉(zhuǎn)換為false,相等運(yùn)算符(‘==’)甚至報(bào)告兩者相等。
if(!undefind){
console.log('undefined is false')
}
if(!null){
console.log('null is false')
}
undefined==null//true
Number(null)//0
Number(undefined)//NaN
null表示空值:var a=null(聲明變量為空)
用法:作為函數(shù)的參數(shù),表示該函數(shù)的參數(shù)是一個(gè)沒有任何內(nèi)容的對(duì)象。
undefined:表示不存在值,就是此處目前不存在任何值。
用法:變量被聲明了,但沒有賦值時(shí),等于undefined.調(diào)用函數(shù)時(shí),應(yīng)該提供的參數(shù)沒有提供,該參數(shù)等于undefined,對(duì)象沒有賦值的屬性,該屬性的值為undefined,函數(shù)沒有返回值時(shí),默認(rèn)返回undefined.
var i//undefined 沒有賦值
function f(x){
console.log(x)//f();undefined 沒有return
}
var o=new object()
o.p//undefined 聲明對(duì)象,調(diào)用對(duì)象屬性。
var x=f();//x undefined
#break與continue的區(qū)別
break是退出循環(huán),而continue是跳過本次循環(huán)執(zhí)行下次循環(huán)
for(var i=1;i<10;i++){
if(i%4===0){
break;
}
console.log(i);
}
i:1/2/3
for(var i=1;i<10;i++){
if(i%4===0){
break;
}
console.log(i);
}i:1/2/3/5/6/7/9
#void 0與undefined的區(qū)別
viod作用是執(zhí)行一個(gè)表達(dá)式,返回undefined
例如:
function fn(){
var undefined=3;
var a;
if(a===undefined){
console.log("===")
}else{
console.log("!==")
}
}
fn()
上述做法是錯(cuò)誤的當(dāng)把undefined賦值了,就不能做判斷了,方法就是a===void 0
#代碼
1. console.log(1+1)輸出結(jié)果是2
原因:兩個(gè)操作數(shù)是數(shù)字,會(huì)做加法運(yùn)算。
console.log("2"+"4")輸出結(jié)果是“24“
原因:兩個(gè)參數(shù)是字符串,會(huì)做字符串拼接
console.log(2+"4")輸出結(jié)果是”24“
原因: 有一個(gè)參數(shù)是字符串,會(huì)做字符串拼接
console.log(+"4")輸出結(jié)果是4
原因: 在只有一個(gè)字符串參數(shù)的時(shí)候,會(huì)嘗試將其轉(zhuǎn)換成數(shù)字
2.
var a=1;
a+++a;//輸出結(jié)果是3,理解為(a++)+a,因?yàn)?+的優(yōu)先級(jí)高于+,所以等同于1+2=3。
typeof a+2//輸出結(jié)果是“number2”typeof的優(yōu)先級(jí)高于+,所以typeof a是number字符串,字符串與數(shù)字相加為拼接字符串。
3.
var a=1;
var b=3;
console.log(a+++b);//輸出結(jié)果是4,++的優(yōu)先級(jí)較高,所以先運(yùn)算,等同于(a++)+b=1+3=4
4. 遍歷數(shù)組,把打印數(shù)組每一項(xiàng)的平方
var arr=[3,4,5]
for(i=0;i<arr.length;i++){
console.log(arr[i]*arr[i]);
}
5. 遍歷json,打印里面的值
var obj = {
name: 'hunger',
sex: 'male',
age: 28
}
for( var key in obj){
console.log(obj[key]);
}
6.
var a = 1, b = 2, c = 3;
var val = typeof a + b || c >0
console.log(val) //輸出結(jié)果是“number2”因?yàn)閠ypeof的權(quán)重高,typeofa輸出是number,字符串與數(shù)字相加是字符串拼接。
var d = 5;
var data = d ==5 && console.log('bb')
console.log(data)//輸出結(jié)果是bb和undefined;先運(yùn)算console.log('bb')輸出bb,然后進(jìn)行判斷d==5(true),console.log('bb')無法轉(zhuǎn)換成布爾值,所以輸出undefined。
var data2 = d = 0 || console.log('haha')
console.log(data2)//輸出結(jié)果是haha和undefined;先運(yùn)算console.log('haha')輸出haha,然后進(jìn)行“||”,因?yàn)?的布爾值是false,console.log('haha')無法轉(zhuǎn)換成布爾值,最后data2的值為undefined。
var x = !!"Hello" + (!"world", !!"from here!!");
console.log(x)//輸出結(jié)果是2。!!"Hello"的結(jié)果為true,(!"world", !!"from here!!") 逗號(hào)運(yùn)算符用于對(duì)兩個(gè)表達(dá)式求值,并返回后一個(gè)表達(dá)式的值,!!"from here!!"的結(jié)果為true,因此(!"world", !!"from here!!")返回true,所以var x = true + true。當(dāng)數(shù)字和布爾值或布爾值與布爾值進(jìn)行+、-、*、/操作時(shí),會(huì)將布爾值轉(zhuǎn)換為數(shù)字,true轉(zhuǎn)換為1,false轉(zhuǎn)換為0。所以var x = true + true轉(zhuǎn)換為var x = 1 + 1,因此最終結(jié)果為2