首頁  >  文章  >  web前端  >  JavaScript型別檢查與內部屬性[[Class]]

JavaScript型別檢查與內部屬性[[Class]]

黄舟
黄舟原創
2017-02-28 14:53:141288瀏覽

所有物件都包含有一個內部屬性[[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)!


#
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn