最近重溫JS高程設計以及與朋友的討論。決定趁熱打鐵記錄JS的各類類型,並作下深刻總結。面試
就是咱們日常用來作簡單賦值的類型。這種數據類型是存在棧中以值得形式存在,賦值時也是直接進行值傳遞segmentfault
是高級的類型,能夠添加方法和熟悉等。真正的數據存在堆中,賦值時是進行址傳遞數組
//舉個例子 var a = [3,4,5]; var b = a;//賦值的是 存儲 a變量的地址。這時候a、b指向同一片內存區域 b[0] = 9;//改變內存區域中的值 a的值也進行更改 console.log(a);//[9,4,5]
咱們都知道只有引用類型才能添加、調用屬性和方法,那爲何基本類型Boolean、String、Number能調用方法?按說它是沒有方法纔對呀!這是由於ECMAScript提供了三個特殊的包裝類型:Boolean、String、Number。每當讀取這個基本類型時,後臺會建立一個對應的基本包裝類型的對象。使得能夠操做這個基本類型了。prototype
1.建立對應包裝類型(Boolean、String、Number)的實例
2.在實例上調用對應的方法
3.銷燬這個實例
//舉個實際操做的例子 var str = 'have a good time'; var str2 = str.charAt(0);//h; str.color = 'red'; console.log(str.color);//undefined
這是由於引用類型和基本包裝類型的生存期不同。引用類型在執行流離開當前做用域時一直存在內存中。自動建立的基本包裝類型的對象,只存在於執行這一行代碼的一瞬間,執行完立馬被銷燬了。這就是爲何咱們給str.color添加對象時打印出來爲undefined。由於在執行完str的color這一行代碼時,自動建立的包裝類型對象被銷燬了。下面console出來的str是新建立的String對象,沒有color這個屬性。設計
typeof 主要是用來判斷基本數據類型code
//返回類型: string、number、boolean、object、undefined、function、Symbol(ES6新增) typeof 123; // "number" typeof 'cherry';// "string" typeof false; //"boolean" typeof undefined; //"undefined" typeof null; // "object" typeof {name:"cherry"};//"object" var fun = function(){}; typeof fun; //"function" typeof new String('xxx');//"object"
因此typeof只能用來判斷基本數據類型。null、引用類型、基本包裝類型都會返回object。對象
instanceof 用法:A instanceof B,主要是判斷A是不是某個對象的實例,簡單來講就是A的原型鏈上(__proto__)是否有B的原型對象(prototype)。ip
// 例子 var obj= {"name":"cherry"}; obj instanceof Object; //true var strObj = new String('hello'); strObj instanceof String;//true var str = 'hello'; str instanceof String;//false
//判斷的原理 就是計算逐級計算左邊對象的__proto__是否等於右邊對象的prototype便可 function instance(left,right){ var obj = right.prototype; var left = left.__proto__; while(true){ if(left === null){ return false; } if(left == obj){ return true; } left = left.__proto__; } }
Object.prototype.toString.call()(點擊看此方法具體原理)
Object.toString()返回對象的字符串表示。可是因爲數值、布爾、字符串、數組都有重寫toString方法,直接調用的時候使用的是自身原型對象上有toString方法則不會往上去找Object的toString方法。這裏強制使用Object原型對象上的toString方法。內存
Object.prototype.toString.call('123');//[object String] var objStr = new String('123');//包裝類型檢測出來也是對應類型而不是對象 Object.prototype.toString.call(objStr);//[object String] Object.prototype.toString.call(123);//[object Number] Object.prototype.toString.call(true);//[object Boolean] Object.prototype.toString.call(null);//[object Null] Object.prototype.toString.call(undefined);//[object Undefined] var obj = {"name":"cherry"}; Object.prototype.toString.call(obj);//[object Object] var arr = [1,2,3]; Object.prototype.toString.call(arr);//[object Array]
總結:使用Object的toString(),能夠檢測出各值的類型。基本數據類型和基本包裝類型返回的值是同樣。因此不用擔憂別人是經過基本包裝類型定義的變量(面試時被問過)原型鏈
面試題:判斷一個值的數據類型
function valueType(data){ var type = null; var typeList = ['Object','Number','Boolean','String','Function','Object','Null','Undefined']; for(var item of typeList){ if(Object.prototype.toString.call(str) == `[object ${item}]`){ type = item; break; } } return type; }