JavaScript 三種方法,可以確定一個值到底是什么類型。
typeof為什么需要確定類型 ?
instanceof
Object.prototype.toString
? 只有確定類型的情況,才知道當前操作對象擁有哪些功能; 比如使用 push,unshfit,shfit 等方法時,那么其必須為數組類型時才能正確使用;
? 當某些情況添加類型檢查時,這樣代碼更加健壯,安全;
typeof 運算符返回一個值的數據類型。
基本語法:
typeof operand or typeof (operand)
operand 是一個表達式,表示對象或原始值,其類型將被返回。括號是可選的.
示例:基本數據類型{ typeof 1 // "number" typeof Number(1) // "number" typeof "" // "string" typeof true // "boolean" typeof null // "object" typeof undefined // "undefined" typeof Symbol // "function" }
當操作數(operand)為基本數據類型,其返回字符串與期望一樣,也能夠辨別當前操作數得類型;
這里需要提及下基本數據類型 null ,為什么 typeof null 返回的字符串為 "object";
在 JavaScript 最初的實現中,JavaScript 中的值是由一個表示類型的標簽和實際數據值表示的。對象的類型標簽是 0。由于 null 代表的是空指針(大多數平臺下值為 0x00),因此,null的類型標簽也成為了 0,typeof null就錯誤的返回了"object"。
示例:引用數據類型typeof new Number(1) // "object" typeof new String() // "object" typeof new Array() // "object" typeof new Date() // "object" typeof new Function() // "function"
從上面看出,所有通過 new 關鍵實例化的構造函數返回都 object 類型. 當然函數是一個例外;
從上述兩個示例可以看出,當typeof 的操作數為基本數據類型、函數返回字符串能夠區分其數據類型;
那么如果需要區分引用類型時需要借助 JavaScript中另外一個運算符;
instanceof 運算符判斷實例對象是不是類(構造函數)的實例
instanceof 工作原理基于原型鏈,也就是說如果在對象的原型鏈上能夠找到構造函數的 prototype 對象,那么該操作就返回 true;
基本語法:**
object instanceof constructor
參數
object
要檢測的對象.
constructor
某個構造函數
let o = new Object(); let bool = new Boolean(); let num = new Number(1); let str = new String(); let arr = new Array(); // 自定義構造函數 function Person(){} function Animal(){} let person = new Person(); let animal = new Animal(); person instanceof Person // true animal instanceof Animal // true o instanceof Object; // true bool instanceof Boolean; // true num instanceof Number; // true str instanceof String; // true arr instanceof Array; // true
這樣彌補 typeof 在檢測引用類型的時的問題;
通過下面的示例,驗證下 instanceof 工作原理:
{ function Person(){} function Animal(){} // 例如自定義定義兩個類 let person = new Person(); let animal = new Animal(); console.log(animal instanceof Object); // => true console.log(animal instanceof Animal); // true console.log(person instanceof Object); // => true console.log(person instanceof Person); // true console.log(person instanceof Animal); // => false console.log(animal instanceof Person); // => false }
上面應該跟我們預期的一樣, 那么有沒有通過一種辦法讓
person instanceof Animal // => true
那么來針對上面作如下調整:
person.__proto__ = Animal.prototype; console.log(person instanceof Animal) // => true console.log(person instanceof Person) // => false
嚴格意義上來說, 上述這么改是沒有意思;這里只是為了驗證 instanceof 如何工作的;其次說明 person instanceof Person 返回 true, 則并不意味著給表達式永遠返回 true, Person.prototype 和 person.__proto__ 都是可變的;
instanceof 和多個全局對象(多個frame或多個window之間的交互)可以定義兩個頁面測試: parent.html、 child.html
// parent.html
// child.html
嚴格上來說value 就是數組,但parent頁面中打印輸出: false ;也就是 parent 頁面中 Array.prototype != window.frames[0].Array.prototype ;
主要引起問題是,因為多個窗口意味著多個全局環境,不同的全局環境擁有不同的全局對象,從而擁有不同的內置類型構造函數.
instanceof 應用 - 檢測作用域的安全function Person(name, age){ this.name = name; this.age = age } // 正常情況下 { let person = new Person("托尼", 20); console.log(person.name,person.age); } // 假如在實例化時候忘記添加 new 關鍵字尼? 會出現什么情況尼? { let person = Person("托尼", 20); console.log(person.name, person.age); // Uncaught TypeError: Cannot read property "name" of undefined // Person 被當作普通的方法執行,其次 name ,age 被添加window上 console.log(name, age); //=> 托尼 20 } // 如何避免這樣情況,在加 new 關鍵字或省略時候都能正常返回實例對象 { function Person(name, age){ if(this instanceof Person) { this.name = name; this.age = age return this; }else { return new Person(name, age); } } let person = Person("托尼", 20); console.log(person.name, person.age); // 托尼 20 }Object.prototype.toString 方法
默認情況下(不覆蓋 toString 方法前提下),任何一個對象調用 Object 原生的 toString 方法都會返回 "[object type]",其中 type 是對象的類型;
每個類的內部都有一個 [[Class]] 屬性,這個屬性中就指定了上述字符串中的 type(構造函數名) ;
舉個例子吧:
console.log(Object.prototype.toString.call([])); // [object Array]
上述中: Array 對應也就當前對象的 type,同樣就是當前對象的構造函數名;
前面在說 instanceof 在多個作用域的情況下,嘗試用這種方式解決:
function isArray(arr){ return Object.prototype.toString.call(arr) === "[object Array]" } console.log(isArray(value)); // true
從輸出來看時完美解決了;
為什么這種方式是可以咧?這里辨別類型根據 構造函數名稱,由于原生數組的構造函數名稱與全局作用域無關,因此使用 toString() 就能保證返回一致的值。
同理其它原生對象檢測也能按照這種方式來,如 Date,RegExp,Function
function isFunction(value) { return Object.prototype.toString.call(value) === "[object Function]" } function isDate(value) { return Object.prototype.toString.call(value) === "[object Date]" } function isRegExp(value) { return Object.prototype.toString.call(value) === "[object RegExp]" } isDate(new Date()); // true isRegExp(/w/); // true isFunction(function(){}); //true
上述代碼,可以作進一步改進,由于 isFunction、isDate、isRegExp 方法中,其實只有 [object ConstructorName] ConstructorName不一樣,可以利用工廠函數再修飾一下:
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
這樣即使要生成其它原生對象驗證函數前面時就簡單多了;
總結:typeof 適用于檢測值類型, 特別注意 null 的問題,這也是面試用經常遇到的.
instanceof 檢測引用類型.
toString 彌補 instanceof 在跨窗口下對類型檢測問題, toString 只適應于原生對象;
對于用戶自定義的對象無法區分的.
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/100084.html
摘要:閉包,原型,原型鏈,繼承對象若干屬性的集合輸出的集中類型標識,其中上面的四種屬于簡單的值類型,不是對象。在實際應用中如何區分一個屬性到底是基本的還是從原型中找到的呢,特別是在循環中由于所有的對象的原型鏈都會找到,因此所有的對象都會有的方法。 閉包,原型,原型鏈,繼承 對象——若干屬性的集合 typeof輸出的集中類型標識,其中上面的四種(undefined, number, strin...
摘要:共享原型鏈現在我們還有另一個對象如圖那么和其實是同一東西,也就是。改進通過第一節可以知道,我們可以通過原型鏈來解決重復創建的問題我們先創建一個士兵原型,然后讓士兵的指向士兵原型。所以這個是原型鏈繼承的缺點,原因是和指向同一個地址即父類的。 在理解繼承之前,需要知道 js 的三個東西: 什么是 JS 原型鏈 this 的值到底是什么 JS 的new 到底是干什么的 想閱讀更多優質文章...
摘要:的數據類型,共有六種。通常,數值字符串布爾值這三種類型,合稱為原始類型的值,即它們是最基本的數據類型,不能再細分了。運算符返回一個布爾值,表示某個對象是否為指定的構造函數的實例。 以下內容摘自阮一峰-JavaScript-標準參考教程 數據類型 JavaScript 語言的每一個值,都屬于某一種數據類型。JavaScript 的數據類型,共有六種。(ES6 又新增了第七種 Symbo...
摘要:一看這二逼就是周杰倫的死忠粉看看控制臺輸出,確實沒錯就是對象。從根本上來說,作用域是基于函數的,而執行環境是基于對象的例如全局執行環境即全局對象。全局對象全局屬性和函數可用于所有內建的對象。全局對象只是一個對象,而不是類。 覺得本人寫的不算很爛的話,可以登錄關注一下我的GitHub博客,博客會堅持寫下去。 今天同學去面試,做了兩道面試題,全部做錯了,發過來給我看,我一眼就看出來了,因為...
摘要:注意客戶端與服務器日期進行傳輸的時候一般都是用大整數時間戳進行傳輸。 前言 一個網站的開發需要要UI、前端、后端三種工程師。現在的企業在招聘前端工程師的時候一般都要求其了解或者掌握一些后端的知識。因此,此文章主要介紹javascript的日期類型,也粗略的介紹一下php的日期類型,以及二者是如何交互數據的。 時間戳 什么是時間戳 時間戳是從格林威治時間1970年1月1日(00:0...
閱讀 2088·2021-11-23 10:13
閱讀 2795·2021-11-09 09:47
閱讀 2742·2021-09-22 15:08
閱讀 3322·2021-09-03 10:46
閱讀 2235·2019-08-30 15:54
閱讀 916·2019-08-28 18:09
閱讀 2432·2019-08-26 18:26
閱讀 2346·2019-08-26 13:48