1. 程式人生 > 實用技巧 >js-資料型別和型別轉換

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 的時候就會出現問題。

- `obj instanceof Array`
- 當用來檢測在不同的 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 型別轉換規則總結