所有物件都包含有一個內部屬性[[Class]]
我們不能直接存取這個屬性,但是我們可以透過一個方法存取
這個方法就是 Object.prototype.toString.call(...)
這也是比較可靠的檢查類型的方法(instanceof、constructor等等不可靠)
比如說我們偵測一個陣列
Object.prototype.toString.call([1,2,3]);
控制台列印"[object Array]"
這裡面的「Array」其實就是呼叫了原生函數Array()內部的[[Class]]屬性
我們可以封裝一個檢測類型的函數
function classOf(obj){ return Object.prototype.toString.call(obj).slice(8,-1); }
函數很簡單,單純地呼叫了Object原型上的toString方法然後截取對我們有用的信息
我們可以來試試這個函數
console.log(classOf({'a':1})); console.log(classOf([1,2,3])); console.log(classOf(function a(){})); console.log(classOf(/a/)); console.log(classOf(123)); console.log(classOf('abc')); console.log(classOf(true)); console.log(classOf(Symbol())); console.log(classOf(undefined)); console.log(classOf(null));
控制台列印
可是我們發現不只是對象,就連基本型別值string、number、boolean都可以列印
這是因為JavaScript為基本類型值包裝了一個封裝對象
使它們變成了對象,而String()、Number()、Boolean()上有屬性[[Class]]
這裡雖然undefined、null沒有對應的原生函數Undefined()和Null(),但仍然有內部屬性回傳
透過這個函數我們可以進行精準的判斷型別
甚至可以判斷參數列表
function demo(){ console.log(classOf(arguments)); } demo();//"Arguments"
回到Object.prototype.toString.call(…)為什麼要透過這麼麻煩的一字串來判斷型別呢
我們可以看看直接呼叫toString()會發生什麼事
console.log({'a':1}.toString()); console.log([1,2,3].toString()); console.log(function a(){}.toString()); console.log(/a/.toString()); console.log(123..toString()); // 只写一个点会被当成小数点,所以再写一个点代表方法调用console.log('abc'.toString()); console.log(true.toString()); console.log(Symbol().toString()); // 基本类型调用方法,会自动封装为对象 // 不能使用undefined.toString()或null.toString()会报错,因为没有对应的封装对象
可以看到只有普通的物件回傳了我們想要的,
這是因為普通物件直接呼叫了頂級原型Object上的toString方法
而陣列、函數以及這些基本包裝物件它們繼承了Obejct的同時
重寫了一些方法
在尋找toString方法的時候,一定是自己原型鏈上的方法優先被找到
所以我們就需要利用call呼叫頂級原型Object.prototype上d的toString方法
以上就是JavaScript類型檢視與內部屬性[[Class]]的內容,更多相關內容請關注PHP中文網(www.php.cn)!