摘要:對于此處的類型都是實例后的對象,并不會深入識別他們的構造函數這里不是數據類型。通過上面的判斷,我們知道它并不能滿足一些內置構造函數創建的偽類型。
在我的第一篇文章里,介紹過JS各大類型并使用typeof進行輸出查看.也有提到過每個函數都有一個自己的內部屬性[[class]],這個class指的是js內部分類.這個類的大致包括:數據類型和構造函數這兩種。
JavaScript類型介紹
我們講過JS的幾大數據類型,也用typeof查看了幾個簡單的數據類型值。那么今天我們再來更寬泛的了解一下這方面的知識。請看如下代碼。
var num = 123; var str = "aflypig"; var bool = true; var arr = [1, 2, 3, 4]; var obj = {name:"aflypig", age:21}; var func = function(){ console.log("this is function"); } var und = undefined; var nul = null; var date = new Date(); var reg = /^[a-zA-Z]{5,20}$/; var error= new Error();
顯然,上次我們只用typeof查看了幾個常用的數據類型,但這次多了一些內置構造函數,還有Array(上次特意沒講Array)類型。那么步入正題,我們怎樣才能準確得獲得這些值(再強調一次,這里不是變量,JS當中衡量類型的是值,變量是儲存值的容器)數據類型呢?
其實,一共有四種方法,但能完全準確地識別出它們的只有一種方法,這也是面試過程中屢見不鮮的一道題。
如果判斷不同類型 typeoftypeof num //number typeif str //string typeof bool //boolean typeof arr //object typeof obj //object typeof func//function typeof und //undefined typeof nul //object typeof date //object tyepof reg //object tyoeof error //object
解析:typeof可以識別簡單基本類型值(比如:number,string,boolean),但對于復合類型(Object,Array,Function)卻只能識別Function。
undefined和null本身就是JS一直以來的bug,此處typeof `undefined`可以識別出正確的類型值,但null被歸類到`Object`大家庭中。 對于此處的 date && reg && error 類型都是實例后的對象,typeof并不會深入識別他們的`構造函數`(這里不是數據類型)。顯然typeof并不能處理這種復雜的類型。
總結:typeof可以看作JS內部已經定義好的各個類型返回其對應的字符串,它不深入值本身,不進行類型轉換,只針對于當前值返回其對應的類型值。同樣的數據類型通過typeof運算符運算都是一樣的,它沒有原理可言,JS就是這樣定義的,我們只管記死它。
instanceof通過上面的typeof判斷,我們知道它并不能滿足一些內置構造函數創建的偽類型。那么,我們這里來使用 constructor 查看他們的構造函數,從而分辨它們的類型。
num instanceof Number //false str instanceof String //false bool instanceof Boolean //false arr instanceof Array //true obj instaneof Object //true func instanceof Function //true und instanceof Object //false nul instanceof Object //false date instanceof Date //true reg instanceof RegExp //true error instanceof Error //true
解析:這里我們使用instanceof來復合判斷的是否為對應類型。首先,我們先看false項,num str bool 這三個在使用instanceof 時并沒有包裝封裝對象且instanceof則是根據
constructornum.constructor .name //Numer str.constructor.name //String bool.constructor.name //Boolean arr.constructor.name //Array obj.constructor.name //Objeact func.constructor.name //Function und.constructor.name // TypeError nul.constructor.name //TypeError date.constructor.name //Date reg.constructor.name // RegExp error.constructor.name //Error
上面除了undefined 和 null 類型錯誤(兩者都沒有屬性值)之外, 其他都可以獲得我們想要的數據類型。但實際真的如此嗎?
// 1?? var Structure = function (){ } var ins = new Structure(); ins.constructor.name //Structure //2?? var Person = function(){} var Student = function(){} Person.prototype = new Student(); var obj = new Person(); obj.constructor === Student
解析:第一種情況,對于通過我們的構造函數生成的實例,不能準確得獲得其對應得類型名稱,這一點恐怕就已經遏制了我們使用這種方式。
第二種情況,由于對象的構造函數是`可變的`,`不準確的`,我們還是無法準確的通過constructor獲得具體的類型.
總結:通過constructor我們可以得到 instance不能得到的 str num bool 這些基本類型值,但另一個問題又浮現出來,constructor的可變性,由于它的不確定性,我們在很多情況下都無法判斷出正確的數據類型,所以使用constructor這個方法也差不多廢了....
[[Class]]解析:此[[class]]指的是隱藏在javascript內部的分類屬性,它不可讀,不可枚舉,不可修改,不可配置。(兩邊出現__下劃線__的屬性都屬于部分瀏覽器支持的屬性。[[]]兩個中括號括起來的屬性屬于JavaScript內部屬性。),我記得上一章說過,JavaScript中一切皆為對象的理念,我們可以強制把它轉換成字符串,使它暴露出內部的[[class]]屬性。
了解了以上各種方法,我們發現它們只能完成部分的類型驗證,有些情況是可變和不準確的。
Object.prototype.toString.call(num); // "[object Number]" Object.prototype.toString.call(str); // "[object String]" Object.prototype.toString.call(bool); // "[object Boolean]" Object.prototype.toString.call(arr); // "[object Array]" Object.prototype.toString.call(func); // "[object Function]" Object.prototype.toString.call(und); // "[object Undefined]" Object.prototype.toString.call(nul); // "[object Null]" Object.prototype.toString.call(date); // "[object Date]" Object.prototype.toString.call(reg); // "[object RegExp]" Object.prototype.toString.call(error); // "[object Error]" arr instanceof Array //true obj instaneof Object //true func instanceof Function //true und instanceof Object //false nul instanceof Object //false date instanceof Date //true reg instanceof RegExp //true error instanceof Error //true
我們通過 Object 的 toString 方法來查看了當前對象的數據類型,我們看到使用這種方式可以完美的查看對應的數據類型,正是我們想要的,而且每個對象都有屬于自己的[[class]],我們可以理解為,它是JavaScript根據內置構造函數做出的內部分類。
對于這種經常使用原生js又難以需求的情況下,怎么能少得了jqquery呢?
以下是與jQuery.type()函數相關的jQuery示例代碼:
jQuery.type( undefined ); // "undefined" jQuery.type( null ); // "null" jQuery.type( true ); // "boolean" jQuery.type( new Boolean(true) ); // "boolean" jQuery.type( 3 ); // "number" jQuery.type( new Number(3) ); // "number" jQuery.type( "test" ); // "string" jQuery.type( new String("test") ); // "string" jQuery.type( function(){} ); // "function" jQuery.type( new Function() ); // "function" jQuery.type( [] ); // "array" jQuery.type( new Array() ); // "array" jQuery.type( new Date() ); // "date" jQuery.type( new Error() ); // "error" // jQuery 1.9 新增支持 jQuery.type( /test/ ); // "regexp" jQuery.type( new RegExp("d+") ); // "regexp"
jquery內部也是通過我們剛才說到的 [[class]]的方式實現的,它返回一個字符串,固定為小寫字母。
我們可以寫行代碼,來簡單的實現jquery中的type方法
function type(o){ var s = Object.prototype.toString.call(o); return s.slice(s.indexOf(" ")+1,s.length-1).toLowerCase(); }
type(false) //boolean
type({}) //object
type([]) //array
type("") //string
type(/^/) //regexp
希望通過本次粗淺的講解能給大家帶來一點收獲,在知道最終有適合的方式時,應該多去考慮使用另外的方式去實現的手段,因為做這樣可以擴展自己的知識范圍。就比如上文,如果從后向前列舉,我想有很多人都不會去思考 constructor 和 instance 的不足以及他們的適用范圍吧,
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/83090.html
摘要:內置函數和對象中內置了一些函數和對象,很多語言都會有內置的方法,直接可以調用開發。根據語法標準提供的內置函數包括和。注意基礎語法提供的內置函數和方法只有這些,像那是瀏覽器提供給我們的。強制類型轉換大家應該都知道。 js基礎 - 變量 *大家對js一定不會陌生,入門很簡單(普通入門),很多人通過網絡資源、書籍、課堂等很多途徑學習js,但是有些js基礎的只是往往被大家遺漏,本章就從js變量...
摘要:內置函數和對象中內置了一些函數和對象,很多語言都會有內置的方法,直接可以調用開發。根據語法標準提供的內置函數包括和。注意基礎語法提供的內置函數和方法只有這些,像那是瀏覽器提供給我們的。強制類型轉換大家應該都知道。 js基礎 - 變量 *大家對js一定不會陌生,入門很簡單(普通入門),很多人通過網絡資源、書籍、課堂等很多途徑學習js,但是有些js基礎的只是往往被大家遺漏,本章就從js變量...
摘要:正文一基本類型檢測為什么說是基本類型檢測對于這三種類型經常用到的基本類型檢測是正確的。為什么說是更好的檢測方法上面的兩種方法要么是只能檢測基本類型,要么是只能檢測引用類型,還存在不支持檢測的情況。 前言 前兩篇文章主要是一直在討論JS類型的轉換,那么怎么才能檢測JS的數據類型呢?檢測數據類型在工程中經常用到,常見的JS類型檢測有三種方法: 1. typeof 2. instanceof...
摘要:如果網頁中包含多個框架,那實際上就存在兩個以上不同的全局執行環境,從而存在兩個以上不同版本的構造函數。如果你從一個框架向另一個框架傳入一個數組,那么傳入的數組與在第二個框架中原生創建的數組分別具有各自不同的構造函數。 1. 首先,typeof肯定是不行的 對于一些基本類型,typeof是可以判斷出數據類型,但是判斷一些引用類型時候,不能具體到具體哪一種類型 再來復習一下typeof的...
閱讀 540·2021-08-31 09:45
閱讀 1647·2021-08-11 11:19
閱讀 883·2019-08-30 15:55
閱讀 821·2019-08-30 10:52
閱讀 2845·2019-08-29 13:11
閱讀 2924·2019-08-23 17:08
閱讀 2833·2019-08-23 15:11
閱讀 3066·2019-08-23 14:33