js-資料型別和型別轉換
一,JS 資料型別
JS 中有 6 種(值)基本型別:booleannumberstringundefined null symbol
引用型別:物件 陣列 函式
二,JS 中使用 typeof 能得到哪些型別?
其中一個奇怪的 null,雖然是基本變數,但是因為設計的時候`null`是全 0,而物件是`000`開頭,所以有這個誤判。
1. boolean
2. number
3. string
4. undefined
5. symbol
6. **object**
7. **function**
typeof null → object typeof array → object
三,instanceof 能正確判斷物件的原理是什麼?
判斷一個物件與建構函式是否在一個原型鏈上
const Person = function () {}; const p1 = new Person(); p1 instanceof Person; // true var str = "hello world"; //注意 str instanceof String; // false var str1 = new String("hello world"); str1 instanceof String; // true
四,如何判斷一個數據是不是 Array
- `Array.isArray(obj)`
- ECMAScript 5 種的函式,當使用 ie8 的時候就會出現問題。
- 當用來檢測在不同的 window 或 iframe 裡構造的陣列時會失敗。這是因為每一個 iframe 都有它自己的執行環境,彼此之間並不共享原型鏈,所以此時的判斷一個物件是否為陣列就會失敗。此時我們有一個更好的方式去判斷一個物件是否為陣列。
- `Object.prototype.toString.call(obj) == '[object Array]'`
- 這個方法比較靠譜
- `obj.constructor === Array`
- constructor 屬性返回對建立此物件的函式的引用
五,Object.prototype.toString 與obj.toString()
Object.prototype.toString
如果是原始型別,他會將原始型別包裝為引用型別,然後呼叫對應方法
function dd() {} var toString = Object.prototype.toString; toString.call(dd); //[object Function] toString.call(new Object()); //[object Object] toString.call(new Array()); //[object Array] toString.call(new Date()); //[object Date] toString.call(new String()); //[object String] toString.call(Math); //[object Math] toString.call(undefined); //[object Undefined] toString.call(null); //[object Null] toString.call(123); //[object Number] toString.call("abc"); //[object String]
同樣是檢測物件 obj 呼叫 toString 方法,obj.toString()的結果和 Object.prototype.toString.call(obj)的結果不一樣,這是為什麼?
這是因為 toString 為 Object 的原型方法,而 Array ,function 等型別作為 Object 的例項,都重寫了 toString 方法。不同的物件型別呼叫 toString 方法時,根據原型鏈的知識,呼叫的是對應的重寫之後的 toString 方法(function 型別返回內容為函式體的字串,Array 型別返回元素組成的字串.....),而不會去呼叫 Object 上原型 toString 方法(返回物件的具體型別),所以採用 obj.toString()不能得到其物件型別,只能將 obj 轉換為字串型別;因此,在想要得到物件的具體型別時,應該呼叫 Object 上原型 toString 方法。
六,實現一個型別判斷函式
1. 判斷 null
2. 判斷基礎型別
3. 使用`Object.prototype.toString.call(target)`來判斷**引用型別**
注意: 一定是使用`call`來呼叫,不然是判斷的 Object.prototype 的型別
之所以要先判斷是否為基本型別是因為:雖然`Object.prototype.toString.call()`能判斷出某值是:number/string/boolean,但是其實在包裝的時候是把他們先轉成了物件然後再判斷型別的。 但是 JS 中包裝型別和原始型別還是有差別的,因為對一個包裝型別來說,typeof 的值是 object
/** * 型別判斷 */ function getType(target) { //先處理最特殊的Null if (target === null) { return "null"; } //判斷是不是基礎型別 const typeOfT = typeof target; if (typeOfT !== "object") { return typeOfT; } //肯定是引用型別了 const template = { "[object Object]": "object", "[object Array]": "array", // 一些包裝型別 "[object String]": "object - string", "[object Number]": "object - number", "[object Boolean]": "object - boolean", }; const typeStr = Object.prototype.toString.call(target); return template[typeStr]; }
七,js型別轉換
看這裡:JS 型別轉換規則總結