判斷資料型別
阿新 • • 發佈:2020-10-16
/** * 判斷一個 變數 的型別,是 陣列、字串、還是物件或者函式等複雜型別。 */ // 首先宣告一些變數 const str = "string", num = 12, isBool = true, isUndefined = undefined, isNull = null, obj = { name: "tom" }, arr = [1], fun = () => {}; /** * 先看最簡單的 typeof 方法 */ console.log(typeof str); console.log(typeof num); console.log(typeof isBool); console.log(typeof isUndefined); console.log(typeof isNull); console.log(typeof obj); console.log(typeof arr); console.log(typeof fun); /** * 輸出:string * number * boolean * undefined * object * object * object * function * * typeof 能判斷簡單型別的變數,但是對於引用型別的陣列,物件等卻無法區別 * 都會識別為 object * */ /** * 使用 instanceof 方法 */ console.log(str instanceof String); // false console.log(num instanceof Number); // false console.log(isBool instanceof Boolean); // false // console.log(isUndefined instanceof undefined); // 報錯 // console.log(isNull instanceof null); // 報錯 console.log(obj instanceof Object); // true console.log(arr instanceof Object); // true console.log(arr instanceof Array); // true console.log(fun instanceof Object); // true console.log(fun instanceof Function); // true /** * 從上面結果可以看出: * 對於簡單型別的字面量宣告,使用 instanceof 方法無法判斷型別 * 對於複雜型別 instanceof 方法對於 Object 都會返回true,因為 陣列,函式本質來說都是物件。 * instanceof 方法的作用是:檢測建構函式的 prototype 屬性是否出現在某個例項物件的原型鏈。 * 即,fun instanceof Object 說明 fun 在 Object 的原型鏈上。並不是一個物件。 * arr, fun 都會沿著原型鏈找到 Object 所以,也會返回true,使用時要注意。 */ let str1 = new String("12"); console.log(`這是一個字串:${str1}`); // 這是一個字串:12 console.log(typeof str1); // object console.log(str1 instanceof String); // true /** * 此時 str1 能沿著原型鏈找到 String */ /** * 使用 原型方法 進行判斷 */ console.log(Object.prototype.toString.call(str)); // [object String] console.log(Object.prototype.toString.call(num)); // [object String] console.log(Object.prototype.toString.call(isBool)); // console.log(Object.prototype.toString.call(isUndefined)); // console.log(Object.prototype.toString.call(isNull)); // console.log(Object.prototype.toString.call(obj)); // console.log(Object.prototype.toString.call(arr)); // console.log(Object.prototype.toString.call(fun)); // /** * [object String] * [object Number] * [object Boolean] * [object Undefined] * [object Null] * [object Object] * [object Array] * [object Function] * * 利用原型上的方法可以正確的判斷出元素型別 * */ /** * 上述三種方法的優劣: * Array.isArray 優於 instanceof, 因為Array.isArray能檢測iframes。 * * Objec.prototype.toString.call() 對於所有的基本資料型別都能進行判斷,包括 undefined 、null。常用於判斷瀏覽器內建物件。 * * instanceof 的內部機制是通過判斷物件的原型鏈中是不是能找到型別的 prototype。 * 使用 instanceof判斷一個物件是否為陣列,instanceof 會判斷這個物件的原型鏈上是否會找到對應的 Array 的原型,找到返回 true,否則返回 false。 * instanceof 只能用來判斷物件型別,原始型別不可以。並且所有物件型別 instanceof Object 都是 true * * Array.isArray()是ES5新增的方法,當不存在 Array.isArray() * 可以用 Object.prototype.toString.call() 實現。如下例子: */ if (!Array.isArray) { Array.isArray = function (arg) { return Object.prototype.toString.call(arg) == "[object Array]"; }; } // Array.isArray 的效能最好,instanceof 比 toString.call 稍微好了一點點。