目錄 typeof instanceof 的內部實現原理 Object.prototype.toString() [[class]] 總結 typeof typeof 操作符唯一的目的就是檢查數據類型 類型 typeof 結果 基本類型 undefined undefined Boolean boolean Number number S
類型
typeof 結果
基本類型
undefined
undefined
Boolean
boolean
Number
number
String
string
Symbol
symbol
BigInt
bigint
null
object
引用類型
Object(Object, Array, Map, Set, Regexp, Date 等)
object
Function
function
目錄
- typeof
- instanceof 的內部實現原理
- Object.prototype.toString()
- [[class]]
- 總結
typeof
typeof?操作符唯一的目的就是檢查數據類型
你會發現用typeof來判斷引用類型時, 都會返回?'object'. 為此, 引入了?instanceof
instanceof?運算符用于檢測構造函數的?prototype?屬性是否出現在某個實例對象的原型鏈上。
var arr = []; arr instanceof Array; // true typeof arr; // "object" function A() {} function B() {} // Javascript 繼承 B.prototype = new A(); var b = new B(); b instanceof A; // true b instanceof B; // true
instanceof 的內部實現原理
- 思路:
利用?原型和原型鏈, 每一個函數都有一個顯式的?prototype, 每一個對象都有一個隱式原型 **proto**, 當我們對象的原型鏈中存在構造函數的顯式原型?prototype時, 我們就可以確定它們之間存在關系;
function myInstanceOf(constructor, instance) { let prototype = constructor.prototype; let proto = instance.__proto__; while (true) { // 說明道原型鏈訂單, 還未找到, 返回 false if (proto === null) { return false; } if (proto === prototype) { return true; } // 繼續向 proto 的原型鏈上遍歷 proto = Object.getPrototypeOf(proto); } }
Object.prototype.toString()
- toString() 方法返回一個表示該對象的字符串。該方法旨在重寫(自定義)派生類對象的類型轉換的邏輯。
- valueOf() 方法返回對象的原始值表示
該方法由?字符串轉換優先調用, 但是?數字的強制轉換和原始值的強制轉換?會優先調用?valueOf, 因為基本的?valueOf()?方法返回一個對象,toString()?方法通常在結束時調用
默認情況下(不重寫?toString方法), 任何一個對象調用?Object原生的?toString方法, 都會返回一個?[object type], 其中?type是對象的類型
let a = {}; a; // {} a.toString(); // "[object Object]"
[[class]]
每個?實例?都有一個 [[Class]] 屬性,這個屬性中就指定了上述字符串中的 type 。 [[Class]] 不能直接地被訪問,但通常可以通過?Object.prototype.toString.call(..)?方法調用來展示。
// Boolean 類型,tag 為 "Boolean" Object.prototype.toString.call(true); // => "[object Boolean]" // Number 類型,tag 為 "Number" Object.prototype.toString.call(10); // => "[object Boolean]" // String 類型,tag 為 "String" Object.prototype.toString.call("1312312"); // => "[object String]" // Array 類型,tag 為 "String" Object.prototype.toString.call([]); // => "[object Array]" // Function 類型, tag 為 "Function" Object.prototype.toString.call(function () {}); // => "[object Function]" // Error 類型(包含子類型),tag 為 "Error" Object.prototype.toString.call(new Error()); // => "[object Error]" // RegExp 類型,tag 為 "RegExp" Object.prototype.toString.call(/\d+/); // => "[object RegExp]" // Date 類型,tag 為 "Date" Object.prototype.toString.call(new Date()); // => "[object Date]" // 其他類型,tag 為 "Object" Object.prototype.toString.call(new (class {})()); // => "[object Object]"
所以可以通過這個方法來判斷每個對象的類型
function generator(type){ return function(value){ return Object.prototype.toString.call(value) === "[object "+ type +"]" } } let isFunction = generator('Function') let isArray = generator('Array'); let isDate = generator('Date'); let isRegExp = generator('RegExp'); isArray([])); // true isDate(new Date()); // true isRegExp(/\w/); // true isFunction(function(){}); //true
以下是一道簡單的面試題
+[1 + [2] + 3] + [1 + 2 + true - false] + [[3 - false + "1"]]; // 拆分一下 let a = +[1 + [2] + 3]; // [2]會首先進行轉換 [2].valueOf, 結果不是基本類型, [2]在調用toString(), 返回'2', 最后 1 + '2' + 3, 1,3進行隱式轉換, +'123' ==> 123 let b = [1 + 2 + true - false]; // [3+true-false], true, false會進行轉換, true=>1, false=>0, 最后1-0==>[1+3]==>[4]==>[4].valueOf().toString()==>'4' let c = [[3 - false + "1"]]; // 先轉換數組里面的一層, [3-0+'1']==>['31'], 結果: [['31']]==>[['31']].valueOf().toString()==>'31' // 最后 a+b+c // 123+'4'+'31'==>123431
面試題目, 如何同時讓等式成立, a===1&&a===2&&a===3
思路:
重寫 a 的 valueOf 方法
let a = { value: [3, 2, 1], valueOf: function () { return this.value.pop(); }, };
總結
- 當一側為 String 類型,被識別為字符串拼接,并會優先將另一側轉換為字符串類型。
- 當一側為 Number 類型,另一側為原始類型,則將原始類型轉換為 Number 類型。
- 當一側為 Number 類型,另一側為引用類型,將引用類型和 Number 類型轉換成字符串后拼接。
- 只有 null undefined '' NaN 0 false 這幾個是 false,其他的情況都是 true,比如 {} , []。
以上就是js類型判斷內部實現原理示例詳解的詳細內容,更多關于js類型判斷內部原理的資料請關注技圈網其它相關文章!
聲明:所有內容來自互聯網搜索結果,不保證100%準確性,僅供參考。如若本站內容侵犯了原著者的合法權益,可聯系我們進行處理。