一障贸、數(shù)據(jù)類型
基本類型
1.值是不可改變的
var name = 'java';
name.toUpperCase(); // 輸出 'JAVA'
console.log(name); // 輸出 'java'
2.占用空間固定胧辽,保存在棧中
原始數(shù)據(jù)類型直接存儲在棧(stack)中的簡單數(shù)據(jù)段谒麦,占據(jù)空間小俄讹、大小固定,屬于被頻繁使用數(shù)據(jù)绕德,所以放入棧中存儲患膛。
棧(stack)為自動分配的內(nèi)存空間,它由系統(tǒng)自動釋放耻蛇;使用一級緩存踪蹬,被調(diào)用時(shí)> 通常處于存儲空間中,調(diào)用后被立即釋放臣咖。
堆(heap)則是動態(tài)分配的內(nèi)存延曙,大小不定也不會自動釋放。使用二級緩存亡哄,生命> 周期與虛擬機(jī)的GC算法有關(guān)
3.值的比較
var a = 1;
var b = true;
console.log(a == b); // true
console.log(a === b); // false
== : 只進(jìn)行值的比較,會進(jìn)行數(shù)據(jù)類型的轉(zhuǎn)換枝缔。
=== : 不僅進(jìn)行值得比較,還要進(jìn)行數(shù)據(jù)類型的比較蚊惯。
引用類型
1.值是可動態(tài)改變的
var a={age:20};
a.age=21;
console.log(a.age) //21
2.占用空間不固定愿卸,保存在堆中
引用數(shù)據(jù)類型存儲在堆(heap)中的對象,占據(jù)空間大截型、大小不固定趴荸,如果存儲在棧中,將會影響程序運(yùn)行的性能宦焦;引用數(shù)據(jù)類型在棧中存儲了指針发钝,該指針指向堆中該實(shí)體的起始地址。當(dāng)解釋器尋找引用值時(shí)波闹,會首先檢索其在棧中的地址酝豪,取得地址后從堆中獲得實(shí)體。
3.比較是引用的比較
當(dāng)從一個(gè)變量向另一個(gè)變量賦引用類型的值時(shí)精堕,同樣也會將存儲在變量中的對象的值復(fù)制一份放到為新變量分配的空間中孵淘。
var a={age:20};
var b=a;
b.age=21;
console.log(a.age==b.age)//true
引用類型存儲在堆中的對象,與此同時(shí)歹篓,在棧中存儲了指針瘫证,而這個(gè)指針指向正是堆中實(shí)體的起始位置揉阎。變量 a 初始化時(shí),a 指針指向?qū)ο髙age:20}的地址背捌,a 賦值給 b 后,b 又指向該對象{age:20}的地址毙籽,這兩個(gè)變量指向了同一個(gè)對象。因此毡庆,改變其中任何一個(gè)變量坑赡,都會相互影響。
此時(shí)扭仁,如果取消某一個(gè)變量對于原對象的引用垮衷,不會影響到另一個(gè)變量。
var a={age:20};
var b=a;
a = 1;
b // {age:20}
上面代碼中乖坠,a 和 b 指向同一個(gè)對象搀突,然后 a 的值變?yōu)?1,這時(shí)不會對 b 產(chǎn)生影響熊泵,b 還是指向原來的那個(gè)對象仰迁。
二、檢驗(yàn)數(shù)據(jù)類型
1.typeof
typeof 返回一個(gè)表示數(shù)據(jù)類型的字符串顽分,返回結(jié)果包括:number徐许、boolean、string卒蘸、symbol雌隅、object、undefined缸沃、function 等 7 種數(shù)據(jù)類型恰起,但不能判斷 null、array 等
typeof Symbol(); // symbol 有效
typeof ''; // string 有效
typeof 1; // number 有效
typeof true; //boolean 有效
typeof undefined; //undefined 有效
typeof new Function(); // function 有效
typeof null; //object 無效
typeof [] ; //object 無效
typeof new Date(); //object 無效
typeof new RegExp(); //object 無效
數(shù)組和對象返回的都是 object趾牧,這時(shí)就需要使用 instanceof 來判斷
2.instanceof
instanceof 是用來判斷 A 是否為 B 的實(shí)例检盼,表達(dá)式為:A instanceof B,如果 A 是 B 的實(shí)例翘单,則返回 true,否則返回 false吨枉。instanceof 運(yùn)算符用來測試一個(gè)對象在其原型鏈中是否存在一個(gè)構(gòu)造函數(shù)的 prototype 屬性。
[] instanceof Array; //true
{} instanceof Object;//true
new Date() instanceof Date;//true
new RegExp() instanceof RegExp//true
關(guān)于數(shù)組的類型判斷哄芜,還可以用 ES6 新增Array.isArray()
Array.isArray([]); // true
instanceof 三大弊端:
- 對于基本類型來說貌亭,字面量方式創(chuàng)建出來的結(jié)果和實(shí)例方式創(chuàng)建的是有一定的區(qū)別的
console.log(1 instanceof Number)//false console.log(new Number(1) instanceof Number)//true
從嚴(yán)格意義上來講,只有實(shí)例創(chuàng)建出來的結(jié)果才是標(biāo)準(zhǔn)的對象數(shù)據(jù)類型值忠烛,也是標(biāo)準(zhǔn)的 Number 這個(gè)類的一個(gè)實(shí)例属提;對于字面量方式創(chuàng)建出來的結(jié)果是基本的數(shù)據(jù)類型值,不是嚴(yán)謹(jǐn)?shù)膶?shí)例美尸,但是由于 JS 的松散特點(diǎn)冤议,導(dǎo)致了可以使用 Number.prototype 上提供的方法。
- 只要在當(dāng)前實(shí)例的原型鏈上师坎,我們用其檢測出來的結(jié)果都是 true恕酸。在類的原型繼承中,我們最后檢測出來的結(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
- 不能檢測 null 和 undefined
對于特殊的數(shù)據(jù)類型 null 和 undefined蕊温,他們的所屬類是 Null 和 Undefined,但是瀏覽器把這兩個(gè)類保護(hù)起來了遏乔,不允許我們在外面訪問使用义矛。
3.嚴(yán)格運(yùn)算符===
只能用于判斷 null 和 undefined,因?yàn)檫@兩種類型的值都是唯一的盟萨。
var a = nulltypeof a // "object"a === null // true
undefined 還可以用 typeof 來判斷
var b = undefined;
typeof b === "undefined" // true
b === undefined // true
4.constructor
constructor 作用和 instanceof 非常相似凉翻。但 constructor 檢測 Object 與 instanceof 不一樣,還可以處理基本數(shù)據(jù)類型的檢測捻激。
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 是無效的對象制轰,因此是不會有 constructor 存在的,這兩種類型的數(shù)據(jù)需要通過其他方式來判斷胞谭。
函數(shù)的 constructor 是不穩(wěn)定的垃杖,這個(gè)主要體現(xiàn)在把類的原型進(jìn)行重寫,在重寫的過程中很有可能出現(xiàn)把之前的 constructor 給覆蓋了丈屹,這樣檢測出來的結(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() 最準(zhǔn)確最常用的方式调俘。首先獲取 Object 原型上的 toString 方法,讓方法執(zhí)行旺垒,讓 toString 方法中的 this 指向第一個(gè)參數(shù)的值彩库。
關(guān)于 toString 重要補(bǔ)充說明:
本意是轉(zhuǎn)換為字符串,但是某些 toString 方法不僅僅是轉(zhuǎn)換為字符串
對于 Number袖牙、String侧巨,Boolean,Array鞭达,RegExp司忱、Date、Function 原型上的 toString 方法都是把當(dāng)前的數(shù)據(jù)類型轉(zhuǎn)換為字符串的類型(它們的作用僅僅是用來轉(zhuǎn)換為字符串的)
Object 上的 toString 并不是用來轉(zhuǎn)換為字符串的畴蹭。
Object 上的 toString 它的作用是返回當(dāng)前方法執(zhí)行的主體(方法中的 this)所屬類的詳細(xì)信息即"[object Object]",其中第一個(gè) object 代表當(dāng)前實(shí)例是對象數(shù)據(jù)類型的(這個(gè)是固定死的)坦仍,第二個(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(new Error()) ; // [object Error]
Object.prototype.toString.call(document) ; // [object HTMLDocument]
Object.prototype.toString.call(window) ; //[object global] window是全局對象global的引用