參考 http://www.sohu.com/a/288719736_463987
js類型值
有兩種數(shù)據(jù)類型儡率,分別是 基本數(shù)據(jù)類型 和 引用數(shù)據(jù)類型 。
基本數(shù)據(jù)類型: Number萎羔, String涂炎, Undefined烂完, Null, Boolean茄菊, Symbol(ES6新增疯潭,表示獨(dú)一無(wú)二的值)
引用數(shù)據(jù)類型: 統(tǒng)稱為 Object 對(duì)象,主要包括對(duì)象面殖,數(shù)組竖哩,函數(shù)
基本數(shù)據(jù)類型
1 值是不可變的
var name = 'javascript'
name.toUpperCase(); // 輸出 'JAVASCRIPT'
console.log(name); // 輸出 'javascript'
由此可得,基本數(shù)據(jù)類型的值是不可改變的
2 存放在棧區(qū)
原始數(shù)據(jù)類型直接存儲(chǔ)在棧(stack)中的簡(jiǎn)單數(shù)據(jù)段脊僚,占據(jù)空間小相叁,大小固定,屬于被頻繁使用數(shù)據(jù),所以放入棧中存儲(chǔ)
3 值的比較
var a = 1;
var b = true;
console.log(a == b); // true
console.log(a === b); // false
== : 只進(jìn)行值的比較,會(huì)進(jìn)行數(shù)據(jù)類型的隱式轉(zhuǎn)換增淹。
===:不僅進(jìn)行值的比較椿访,還要進(jìn)行數(shù)據(jù)類型的比較
引用數(shù)據(jù)類型
1 值是可變的
var a = { age: 20};
a.age= 21
console.log(a.age) //21
上面代碼說(shuō)明引用類型可以擁有屬性和方法虑润,并且是可以動(dòng)態(tài)改變的成玫。
2 同時(shí)保存在棧內(nèi)存和堆內(nèi)存
引用數(shù)據(jù)類型存儲(chǔ)在堆 (heap) 中的對(duì)象,占據(jù)空間大、大小不固定,如果存儲(chǔ)在棧中拳喻,將會(huì)影響程序運(yùn)行的性能哭当;引用數(shù)據(jù)類型在棧中存儲(chǔ)了指針,該指針指向堆中該實(shí)體的起始地址舞蔽。當(dāng)解釋器尋找引用值時(shí)荣病,會(huì)首先檢索其在棧中的地址码撰,取得地址后從堆中獲得實(shí)體渗柿。
3 比較是引用的比較
當(dāng)從一個(gè)變量向另一個(gè)變量賦引用類型的值時(shí),同樣也會(huì)將存儲(chǔ)在變量中的對(duì)象的值賦值一份放在新變量分配的空間中脖岛。
var a = { age: 20};
var b = a;
b.age = 21;
console.log(a.age==b.age) //true
上面我們講到基本類型和引用類型存儲(chǔ)于內(nèi)存的位置不同朵栖,引用類型存儲(chǔ)在堆中的對(duì)象,與此同時(shí)柴梆,在棧中存儲(chǔ)了指針陨溅,而這個(gè)指針指向正是堆中實(shí)體的起始位置。變量 a 初始化時(shí)绍在,a 指針指向?qū)ο髙age:20} 的 地址门扇,a 賦值給 b 后,b 又指向該對(duì)象 {age:20} 的地址,這兩個(gè)變量指向了同一個(gè)對(duì)象偿渡。因此臼寄,改變其中任何一個(gè)變量,都會(huì)相互影響溜宽。
此時(shí)吉拳,如果取消某一個(gè)變量對(duì)于原對(duì)象的引用,不會(huì)影響到另一個(gè)變量适揉。
var a = { age: 20 };
var b = a;
a = 1;
b // {age:20}
上面代碼中留攒,a 和 b 指向同一個(gè)對(duì)象,然后 a 的值變?yōu)?1嫉嘀,這時(shí)不會(huì)對(duì) b 產(chǎn)生影響炼邀,b 還是指向原來(lái)的那個(gè)對(duì)象。
js檢查數(shù)據(jù)類型
1 typeof
typeof 返回一個(gè)表示數(shù)據(jù)類型的字符串剪侮,返回結(jié)果包括: number拭宁, boolean,string, symbol红淡,object不狮, undefined, function 7種數(shù)據(jù)類型 在旱,但是不能判斷 null 和 array(也屬于object)等
typeof Symbol(); // symbol 有效
typeof ''; // string 有效
typeof 1; // number 有效
typeof true; //boolean 有效
typeof undefined; //undefined 有效
typeof new Function(); // function 有效
typeof null; //object 無(wú)效
typeof [] ; //object 無(wú)效
typeof new Date(); //object 無(wú)效
typeof new RegExp(); //object 無(wú)效
數(shù)組和對(duì)象返回的都是 object摇零,這時(shí)就需要使用 instanceof 來(lái)判斷
2 instanceof
instanceof 是用來(lái)判斷 A 是否為 B 的實(shí)例,表達(dá)式為:A instanceof B桶蝎,如果 A 是 B 的實(shí)例驻仅,則返回 true,否則返回 false登渣。instanceof 運(yùn)算符用來(lái)測(cè)試一個(gè)對(duì)象在其原型鏈中是否存在一個(gè)構(gòu)造函數(shù)的 prototype 屬性噪服。
[] instanceof Array // true
{} instanceof Object // true
new Date() instanceof Date // true
new RegExp() instanceof RegExp // true
Array.isArray([]); // true
數(shù)組的判斷還可以用 ES6 新增的 Array.isArray(obj)
由于 instanceof 是對(duì) 對(duì)象實(shí)例是否 某對(duì)象的原型或者說(shuō)原型鏈上的 方法,所以會(huì)有一些弊端
instanceof 三大弊端
- 對(duì)于基本數(shù)據(jù)類型來(lái)說(shuō)胜茧,字面量方式創(chuàng)建出來(lái)的結(jié)果和實(shí)例方式創(chuàng)建出來(lái)的是有區(qū)別的
console.log( 1 instanceof Number) //false
console.log( new Number(1) instanceof Number) //true
其實(shí)就是字面量創(chuàng)建的 基本數(shù)據(jù)類型 用 typeof 可以檢測(cè)到對(duì)應(yīng)的類型粘优,用 instanceof 需要?jiǎng)?chuàng)建對(duì)象才能用。
從嚴(yán)格意義上來(lái)講呻顽,只有實(shí)例創(chuàng)建出來(lái)的結(jié)果才是標(biāo)準(zhǔn)的對(duì)象數(shù)據(jù)類型值雹顺,也是標(biāo)準(zhǔn)的 Number 這個(gè)類的一個(gè)實(shí)例;對(duì)于字面量方式創(chuàng)建出來(lái)的結(jié)果是基本的數(shù)據(jù)類型值廊遍,不是嚴(yán)謹(jǐn)?shù)膶?shí)例嬉愧,但是由于 JS 的松散特點(diǎn),導(dǎo)致了可以使用 Number.prototype 上提供的方法喉前。
只要在當(dāng)前實(shí)例的原型鏈上没酣,我們用其檢測(cè)出來(lái)的結(jié)果都是 true。在類的原型繼承中卵迂,我們最后檢測(cè)出來(lái)的結(jié)果未必準(zhǔn)確裕便。
var arr = [1, 2, 3];
console.log(arr instanceof Array) // true
console.log(arr instanceof Object); // true
function fn() {}
console.log(fn instanceof Function) // true
console.log(fn instanceof Object) // true
對(duì)于特殊的數(shù)據(jù)類型 null 和 undefined,他們的所屬類是 Null 和 Undefined狭握,但是瀏覽器把這兩個(gè)類保護(hù)起來(lái)了闪金,不允許我們?cè)谕饷嬖L問(wèn)使用。
- 嚴(yán)格運(yùn)算符 ===
只能用于判斷 null 和 undefined论颅,因?yàn)檫@兩種類型的值都是唯一的哎垦。
var a = null
typeof a // "object"
a === null // true
// undefined 還可以用 typeof 來(lái)判斷
var b = undefined;
typeof b === "undefined" // true
b === undefined // true
- constructor(構(gòu)造函數(shù)的構(gòu)造器)
constructor 作用和 instanceof 非常相似。但 constructor 檢測(cè) Object 與 instanceof 不一樣恃疯,還可以處理基本數(shù)據(jù)類型的檢測(cè)漏设。
var aa=[ 1, 2];
console.log(aa.constructor=== Array); //true
console.log(aa.constructor=== RegExp); //false console.log((1).constructor=== Number); //true
var reg= /^$/;
console.log(reg.constructor=== RegExp); //true console.log(reg.constructor=== Object); //false
constructor 兩大弊端:
null 和 undefined 是無(wú)效的對(duì)象,因此是不會(huì)有 constructor 存在的今妄,這兩種類型的數(shù)據(jù)需要通過(guò)其他方式來(lái)判斷郑口。
函數(shù)的 constructor 不穩(wěn)定鸳碧,主要是類的原型進(jìn)行重寫,在重寫的過(guò)程中有可能把之前的constructor給覆蓋了犬性,這樣檢測(cè)出來(lái)的結(jié)果就是不準(zhǔn)確的
function Fn() {}
Fn.prototype = new Array()
var f = new Fn()
console.log(f.constructor) // Array
5. Object.prototype.toString.call()
Object.prototype.toString.call() 是檢測(cè)類型最準(zhǔn)確的常用方法瞻离。
首先獲取到 Object 原型上的 toString()方法,讓方法執(zhí)行乒裆, 讓 toString 方法中的 this 指向第一個(gè)參數(shù)的值
注意:關(guān)于toString的補(bǔ)充說(shuō)明
本意是轉(zhuǎn)換為字符串套利,但是某些 toString 不僅僅是轉(zhuǎn)換成字符串
對(duì)于 Number,String鹤耍,Boolean肉迫,Array,RegExp稿黄,Date喊衫,F(xiàn)unction 原型上的 toString 方法都是把當(dāng)前的數(shù)據(jù)類型轉(zhuǎn)換為字符串的類型(它們的作用僅僅是用來(lái)轉(zhuǎn)換為字符串的)
Object 上的 toString 并不是用來(lái)轉(zhuǎn)換成字符串的
Obect 上的 toString()方法,它的作用是返回當(dāng)前方法執(zhí)行的主體(方法中的 this )所屬類的詳細(xì)信息即 “[object Object]”杆怕, 其中第一個(gè) object 代表當(dāng)前實(shí)例是對(duì)象數(shù)據(jù)類型的(這個(gè)是固定死的族购,不會(huì)改變),第二個(gè) Object 代表的是 this 所屬的類是 Object财著。
Object.prototype.toString.call('') ; // [object String]
Object.prototype.toString.call(1) ; // [object Number]
Object.prototype.toString.call(true) ; // [object Boolean] Object.prototype.toString.call(undefined) ; // [object Undefined] Object.prototype.toString.call(null) ; // [object Null]
Object.prototype.toString.call(new Function()) ; // [object Function] Object.prototype.toString.call(new Date()) ; // [object Date]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
Object.prototype.toString.call( newError()) ; // [object Error]
Object.prototype.toString.call( document) ; // [object HTMLDocument]
Object.prototype.toString.call( window) ; //[object global] window是全局對(duì)象global的引用
联四?撑碴?撑教? 找一下這個(gè)原理