javascript數(shù)據(jù)類(lèi)型詳解
一、六種數(shù)據(jù)類(lèi)型 (弱類(lèi)型數(shù)據(jù))
1.基本數(shù)據(jù)類(lèi)型(5種):Undefined、Null、Boolean、Number、String
2.引用數(shù)據(jù)類(lèi)型(1種):Object 例如: Function Date Array ...
在js中定義變量的時(shí)候無(wú)需指定類(lèi)型。比如定義一個(gè)變量 var num = 16, 而此時(shí)我們也可以把一個(gè)字符串賦值給這個(gè)變量 num = "this is a string",這樣也是合法的。那可能有的朋友覺(jué)得js好簡(jiǎn)單,定義變量的時(shí)候連類(lèi)型是什么都不用管,是這樣的嗎?那下面我們來(lái)看一下:
(1). 16 + 16 的運(yùn)算結(jié)果是什么呢,這個(gè)很簡(jiǎn)單是 32
(2). 我們把第一個(gè) 16 用雙引號(hào)引起來(lái),理解為字符串。 "16" + 16 的運(yùn)算結(jié)果是什么呢,還是 32 嗎?肯定不是啦,此時(shí)這里的理解為字符串拼接,答案為 “1616” 這樣一個(gè)字符串。
(3). 我們繼續(xù)看同樣是那如果同樣是字符串或者是數(shù)字,我們把 + 變成 -,"16" - 16 此時(shí)運(yùn)算結(jié)果是什么呢? 答案是 0。這里的理解為數(shù)字的運(yùn)算所以答案就是0。
小結(jié):js在定義一個(gè)變量的時(shí)候雖然不用指定變量的數(shù)據(jù)類(lèi)型,但是在涉及到操作符等等的一些運(yùn)算的時(shí)候,背后往往有很多的隱式轉(zhuǎn)換邏輯。
二、隱式轉(zhuǎn)換 (+ 和 -,== 和 ===)
1.借著上面提到的我們舉一個(gè)例子:
"16" + 6 // "166" (字符串拼接) "16" - 6 // 10?。〝?shù)字運(yùn)算)
我們往往可以利用(+/-)規(guī)則來(lái)進(jìn)行轉(zhuǎn)換類(lèi)型。
比如:我們想把變量num 轉(zhuǎn)換成數(shù)字類(lèi)型,一個(gè)非常簡(jiǎn)單的方法我們就可以 num - 0。又或者我們想把num轉(zhuǎn)換成 String 類(lèi)型,我們?cè)撛趺崔k呢,對(duì)就是加一個(gè)空的字符串 num + ""。
2. == 和 ===
(一)、相等運(yùn)算符 (==)
1、如果一個(gè)值是null,另一個(gè)是undefined,則它們相等。
2、如果一個(gè)值是數(shù)字,另一個(gè)是字符串,先將字符串轉(zhuǎn)換為數(shù)字,然后使用轉(zhuǎn)換后的值比較。
3、如果其中一個(gè)值是true,則將其轉(zhuǎn)換為1再進(jìn)行比較。如果其中一個(gè)值是false,則將基轉(zhuǎn)換為0再進(jìn)行比較。
4、如果一個(gè)值是對(duì)象,另一個(gè)值是數(shù)字或字符串,則將對(duì)象轉(zhuǎn)換為原始值,然后再進(jìn)行比較。對(duì)象通過(guò)toString()方法或valueOf()方法轉(zhuǎn)換為原始值。JavaScript核心的內(nèi)置類(lèi)首先嘗試使用valueOf(),再?lài)L試使用toString(),除了日期類(lèi),日期類(lèi)只使用toString()轉(zhuǎn)換。那些不是JavaScript語(yǔ)言核心中的對(duì)象則通過(guò)各自的實(shí)現(xiàn)中定義的方法轉(zhuǎn)換為原始值。
5、其他不同類(lèi)型之間的比較均不相等.
例如:
null == undefined, //true “16” == 16, //true 0 == false, //true [1,2] == [1,2], //false new Object() == new Object(), //false new Object().toString() == new Object().toString(), //true new String("aaa") == "aaa", //true new String("11") == 11, //true
(二)、嚴(yán)格等于(===)
1、首先判斷他們的類(lèi)型,如果兩個(gè)值類(lèi)型不相同,則它們不相等,直接返回 false。
// “16” === 16, //false
2、如果兩個(gè)值都是null或者都是undefined,則它們才相等。
// null === null, //true, undefined=== undefined, //true undefined === null //false
3、如果兩個(gè)值都是布爾值true或false,則它們相等。
4、如果其中一個(gè)值是NaN,或者兩個(gè)兩個(gè)值都是NaN,則它們不相等。NaN和其他任何值都是不相等的,包括它本身?。?!通過(guò)x!==x來(lái)判斷x是否為NaN,只有在x為NaN的時(shí)候,這個(gè)表達(dá)式的值才為true。
5、如果兩個(gè)值為數(shù)字,且數(shù)值相等,則它們相等。如果一個(gè)為0,另一個(gè)為-0,則它們同樣相等。
6、如果兩個(gè)值為字符串,且所含的對(duì)應(yīng)位上的16位數(shù)完全相等,則它們相等。如果它們的長(zhǎng)度或內(nèi)容不同,則它們不等。兩個(gè)字符串可能含義完全一樣且所顯示出手字符也一樣,但具有不同編碼的16位值。JavaScript并不對(duì)Unicode進(jìn)行標(biāo)準(zhǔn)化的轉(zhuǎn)換,因此像這樣的字符串通過(guò)"==="和"=="運(yùn)算符的比較結(jié)果也不相等。
7、如果兩個(gè)引用值同一個(gè)對(duì)象、數(shù)組或函數(shù),則它們是相等的。如果指向不同的對(duì)象,則它們是不等的。盡管兩個(gè)對(duì)象具有完全一樣的屬性。
三、包裝對(duì)象
定義:在JavaScript中,“一切皆對(duì)象”,數(shù)組和函數(shù)本質(zhì)上都是對(duì)象,就連三種原始類(lèi)型的值——數(shù)值、字符串、布爾值——在一定條件下,也會(huì)自動(dòng)轉(zhuǎn)為對(duì)象,也就是原始類(lèi)型的“包裝對(duì)象”。
通俗來(lái)講:字符串,數(shù)值,字符串,這些單身狗看其它人都有對(duì)象,非常不爽,所以自己也搞了個(gè)對(duì)象,名字叫包裝。
1.一般來(lái)說(shuō),只有對(duì)象是可以對(duì)屬性進(jìn)行讀寫(xiě)操作的。但是聰明的騷年,你有沒(méi)有發(fā)現(xiàn),平時(shí)我們用得很多的字符串方法和屬性,都是直接通過(guò)”.”操作符訪問(wèn)的。比如:
console.log("hello world".length); console.log("this a string".indexOf("a"));
2.其實(shí),在我們調(diào)用這些方法和屬性時(shí),JS內(nèi)部已經(jīng)隱式地幫我們幫創(chuàng)建了一個(gè)包裝對(duì)象了,以上的實(shí)際的情形應(yīng)該是這樣的:
console.log(new String("hello world").length); console.log(new String("this a string").indexOf("a"));
3.但是兩者還是有區(qū)別的,
區(qū)別1:
瀏覽器自己隱式創(chuàng)建的包裝對(duì)象和你顯式創(chuàng)建的包裝對(duì)象不嚴(yán)格相等。簡(jiǎn)單來(lái)說(shuō),雖然說(shuō)表面JS對(duì)親生的與領(lǐng)養(yǎng)的一樣,但實(shí)際上,親生的不等于領(lǐng)養(yǎng)的。
var a1 = "test", a2=new String("test"); console.log(a1 == a2);//true console.log(a1 === a2);//false
區(qū)別2:
隱式創(chuàng)建的包裝對(duì)象,在使用完后之后就會(huì)被拋棄了。簡(jiǎn)單來(lái)說(shuō)就是,一個(gè)大大的負(fù)心漢,上完我,就拋棄,還重新去找其他對(duì)象。
拿我們開(kāi)頭的那道題來(lái)說(shuō):
test.a = "hello";
這里隱式創(chuàng)建了一個(gè)包裝對(duì)象,所以這里賦值不會(huì)報(bào)錯(cuò)。
console.log(test.a);
這里之前的包裝對(duì)象已經(jīng)被拋棄了,但是使用了"."運(yùn)算符,所以又創(chuàng)建一個(gè)新的包裝對(duì)象,但是這個(gè)對(duì)象的屬性a并沒(méi)有賦值,所以屬性a的值是undefined。
說(shuō)到實(shí)際運(yùn)用中,有的瀏覽器性能不是很好,比如說(shuō)低版本IE,當(dāng)頻繁處理字符串時(shí),效率會(huì)很低。所以很多時(shí)候,我們還不如直接顯式地創(chuàng)建包裝對(duì)象,防止瀏覽器過(guò)多地創(chuàng)建隱式的包 裝對(duì)象,提升性能。
//不推薦使用種方法 var example = "this is a example"; //推薦使用這種方法,提升性能。 var example2 = new String("this is a example");
四、類(lèi)型檢測(cè)
在js中檢測(cè)類(lèi)型的方法有很多,比如 typeof、instanceof、Object.prototype.toString、constructor、duck type
1. typeof 運(yùn)算符,有兩種方式 typeof + 檢測(cè)目標(biāo) 或者 typeof (檢測(cè)目標(biāo)),該方法適用于基本數(shù)據(jù)類(lèi)型和函數(shù)的檢測(cè)(遇到null失效),返回的結(jié)果都是字符串
typeof 100 “number”
typeof true “boolean”
typeof("hello") "String"
typeof Function “Function”
typeof undefined “undefined”
typeof null “Object” 歷史遺留的問(wèn)題,為了兼容
typeof NaN “number” 判斷NaN的方法可以用isNaN(NaN)來(lái)判斷,如果返回true就是NaN
typeof new Object() “Object”
typeof [1,2] "Object"
大家可能注意到了,typeof在檢測(cè)對(duì)象類(lèi)型的時(shí)候是無(wú)法區(qū)分的,此時(shí)我們就要用第二種方法instanceof
2.instanceof運(yùn)算符(適用于自定義對(duì)象或者原生對(duì)象數(shù)據(jù)類(lèi)型的檢測(cè)),基于原型鏈的類(lèi)型檢測(cè)
比如判斷一個(gè)對(duì)象是不是數(shù)組: [1,2] instanceof Array 返回 true
obj instanceof Object :它期望左操作數(shù)obj 是一個(gè)對(duì)象,如果是一個(gè)數(shù)字1,2,3或者true,false時(shí)就會(huì)直接返回false。
它期望右操作數(shù)是一個(gè)函數(shù)對(duì)象或者是函數(shù)構(gòu)造器,如果不是就會(huì)拋出Typeerror異常
instanceof 工作的一個(gè)大概的原理就是它會(huì)判斷左操作數(shù)這樣一個(gè)對(duì)象的原型鏈上是否有右邊這個(gè)構(gòu)造函數(shù)的prototype屬性
我們舉一個(gè)例子:
function Person(){} function Student(){} Student.prototype = new Person(); Student.protype.constructor = Student var a = new Person(); var b = new Student(); ----------------------------------------- a instanceof Person // true b instanceof Student //true a instanceof Student //false b instanceof Person //true
注意:不同window之間和跨iframe之間是不可以使用instanceof的,雖然看著是同一個(gè)對(duì)象但是在不同window之間和跨iframe之間是不同的對(duì)象,每個(gè)iframe下都有自己的一套原型鏈,跨frame實(shí)例化的對(duì)象彼此是不共享原型鏈,因此會(huì)返回false
3.Object.prototype.toString 函數(shù)方法
Object.prototype.toString.call()或者Object.prototype.toString.apply()
例如:
Object.prototype.toString.call([]) //"[object Array]" Object.prototype.toString.call(function(){}) //"[object Function]" Object.prototype.toString.call(undefined) //"[object Undefined]" Object.prototype.toString.call(null) //"[object Null]"
注意:1.解決了跨iframe 失效的問(wèn)題
2.IE 6,7,8下 Object.prototype.toString.call(null或undefined) //"[object Object]"
4.constructor方法
function A(){}; function B(){}; A.prototype = new B(); var aObj = new A(); -------------------------------- aObj.constructor === B; //true; aObj.constructor === A; //false;
注意:類(lèi)繼承時(shí)會(huì)出現(xiàn)問(wèn)題
5.duck type(鴨子類(lèi)型)
比如檢測(cè)數(shù)組時(shí),我們可以檢測(cè)他有沒(méi)有push()方法等等
以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持腳本之家!
相關(guān)文章
用JS將搜索的關(guān)鍵字高亮顯示實(shí)現(xiàn)代碼
這篇文章介紹了JS將搜索的關(guān)鍵字高亮顯示實(shí)現(xiàn)代碼,有需要的朋友可以參考一下2013-11-11js 實(shí)現(xiàn)省市區(qū)三級(jí)聯(lián)動(dòng)菜單效果
本文主要分享了js實(shí)現(xiàn)省市區(qū)三級(jí)聯(lián)動(dòng)菜單效果的示例代碼。具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-02-02javascript實(shí)現(xiàn)前端成語(yǔ)點(diǎn)擊驗(yàn)證
這篇文章主要介紹了javascript實(shí)現(xiàn)前端成語(yǔ)點(diǎn)擊驗(yàn)證,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06JS填寫(xiě)銀行卡號(hào)每隔4位數(shù)字加一個(gè)空格
這篇文章主要介紹了JS填寫(xiě)銀行卡號(hào)每隔4位數(shù)字加一個(gè)空格的相關(guān)資料,需要的朋友可以參考下2016-12-12利用JavaScript實(shí)現(xiàn)網(wǎng)頁(yè)版2048小游戲
這篇文章主要介紹了如何利用HTML+CSS+JS編寫(xiě)一個(gè)網(wǎng)頁(yè)版的2048小游戲,代碼簡(jiǎn)單易懂對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-11-11