<pre id="bbfd9"><del id="bbfd9"><dfn id="bbfd9"></dfn></del></pre>

          <ruby id="bbfd9"></ruby><p id="bbfd9"><mark id="bbfd9"></mark></p>

          <p id="bbfd9"></p>

          <p id="bbfd9"><cite id="bbfd9"></cite></p>

            <th id="bbfd9"><form id="bbfd9"><dl id="bbfd9"></dl></form></th>

            <p id="bbfd9"><cite id="bbfd9"></cite></p><p id="bbfd9"></p>
            <p id="bbfd9"><cite id="bbfd9"><progress id="bbfd9"></progress></cite></p>

            如何檢查JavaScript變量的類型

            時間:2025-12-15 15:42:28 java語言

            如何檢查JavaScript變量的類型

              JavaScript基本數據類型有5種:字符串、數字、布爾、null、undefined。 用戶定義的類型(object)并沒有類的聲明,因此繼承關系只能通過構造函數和原型鏈來檢查。 如何檢查一個變量的類型?以下僅供參考!

              先給結論:

              如果你要判斷的是基本數據類型或JavaScript內置對象,使用toString; 如果要判斷的時自定義類型,請使用instanceof。

              不同的編程語言都有自己的方式來提供類型信息,例如C#的反射、C++的Traits, JavaScript提供類型信息的方式更加靈活,因而也容易產生很多誤用。 下面來分析常見類型檢查手段的區別:typeof, instanceof, constructor, toString。

              如果你在尋找類型轉換的解決方案,而非類型檢查,請移步JavaScript類型轉換。

              typeof

              typeof 操作符返回的是類型字符串,它的返回值有6種取值:

              typeof 3 /pic/p>

              typeof "abc" /pic/p>

              typeof {} /pic/p>

              typeof true /pic/p>

              typeof undefined /pic/p>

              typeof function(){} /pic/p>

              所有對象的typeof都是"object",不能用于檢測用戶自定義類型。 比如Date, RegExp, Array, DOM Element的類型都是"object":

              typeof [] /pic/p>

              typeof還有一個知名的bug:

              typeof null  /pic/p>

              null是基本數據類型,它的類型顯然是Null。其實這也反映了null的語義, 它是一個空指針表示對象為空,而undefined才表示什么都沒有。 總之,typeof只能用于基本數據類型檢測,對于null還有Bug。

              instanceof

              instanceof操作符用于檢查某個對象的原型鏈是否包含某個構造函數的prototype屬性。例如:

              obj instanceof Widget

              obj的原型鏈上有很多對象(成為隱式原型),比如:obj.__proto__, obj.__proto__.__proto__, ...如果這些對象里存在一個p === Widget.prototype,那么instanceof結果為true,否則為false。

              instanceof是通過原型鏈來檢查類型的,所以適用于任何"object"的類型檢查。

              /pic/p>

              function Animal(){ }

              (new Animal) instanceof Animal  /pic/p>

              /pic/p>

              function Cat(){}

              Cat.prototype = new Animal

              (new Cat) instanceof Animal   /pic/p>

              instanceof也可以用來檢測內置兌現,比如Array, RegExp, Object, Function:

              [1, 2, 3] instanceof Array /pic/p>

              /abc/ instanceof RegExp /pic/p>

              ({}) instanceof Object /pic/p>

              (function(){}) instanceof Function /pic/p>

              instanceof對基本數據類型不起作用,因為基本數據類型沒有原型鏈。

              3 instanceof Number /pic/p>

              true instanceof Boolean /pic/p>

              'abc' instanceof String /pic/p>

              null instanceof XXX /pic/p>

              undefined instanceof XXX /pic/p>

              但你可以這樣:

              new Number(3) instanceof Number /pic/p>

              new Boolean(true) instanceof Boolean /pic/p>

              new String('abc') instanceof String /pic/p>

              但這時你已經知道數據類型了,類型檢查已經沒有意義了。

              constructor

              constructor屬性返回一個指向創建了該對象原型的函數引用。需要注意的是,該屬性的值是那個函數本身。例如:

              function Animal(){}

              var a = new Animal

              a.constructor === Animal /pic/p>

              constructor不適合用來判斷變量類型。首先因為它是一個屬性,所以非常容易被偽造:

              var a = new Animal

              a.constructor === Array

              a.constructor === Animal /pic/p>

              另外constructor指向的是最初創建當前對象的函數,是原型鏈最上層的那個方法:

              function Cat(){}

              Cat.prototype = new Animal

              function BadCat(){}

              BadCat.prototype = new Cat

              (new BadCat).constructor === Animal /pic/p>

              Animal.constructor === Function  /pic/p>

              與instanceof類似,constructor只能用于檢測對象,對基本數據類型無能為力。 而且因為constructor是對象屬性,在基本數據類型上調用會拋出TypeError異常:

              null.constructor   /pic/p>

              undefined.constructor /pic/p>

              與instanceof不同的是,在訪問基本數據類型的屬性時,JavaScript會自動調用其構造函數來生成一個對象。例如:

              (3).constructor === Number /pic/p>

              true.constructor === Boolean /pic/p>

              'abc'.constructor === String /pic/p>

              /pic/p>

              (new Number(3)).constructor === Number

              (new Boolean(true)).constructor === Boolean

              (new String('abc')).constructor === String

              這種將一個值類型轉換為對象引用類型的機制在其他語言中也存在,在C#中稱為裝箱(Boxing)。

              跨窗口問題

              我們知道Javascript是運行在宿主環境下的,而每個宿主環境會提供一套ECMA標準的內置對象,以及宿主對象(如window, document),一個新的窗口即是一個新的宿主環境。 不同窗口下的內置對象是不同的實例,擁有不同的內存地址。

              而instanceof和constructor都是通過比較兩個Function是否相等來進行類型判斷的。 此時顯然會出問題,例如:

              var iframe = document.createElement('iframe');

              var iWindow = iframe.contentWindow;

              document.body.appendChild(iframe);

              iWindow.Array === Array   /pic/p>

              /pic/p>

              iWindow.Array === window.Array /pic/p>

              因此iWindow中的數組arr原型鏈上是沒有window.Array的。請看:

              iWindow.document.write('

              ');

              iWindow.arr instanceof Array   /pic/p>

              iWindow.arr instanceof iWindow.Array /pic/p>

              toString

              toString方法是最為可靠的類型檢測手段,它會將當前對象轉換為字符串并輸出。 toString屬性定義在Object.prototype上,因而所有對象都擁有toString方法。 但Array, Date等對象會重寫從Object.prototype繼承來的toString, 所以最好用Object.prototype.toString來檢測類型。

              toString = Object.prototype.toString;

              toString.call(new Date); /pic/p>

              toString.call(new String); /pic/p>

              toString.call(Math);  /pic/p>

              toString.call(3);   /pic/p>

              toString.call([]);   /pic/p>

              toString.call({});   /pic/p>

              /pic/p>

              toString.call(undefined); /pic/p>

              toString.call(null);  /pic/p>

              toString也不是完美的,它無法檢測用戶自定義類型。 因為Object.prototype是不知道用戶會創造什么類型的, 它只能檢測ECMA標準中的那些內置類型。

              toString.call(new Animal) /pic/p>

              因為返回值是字符串,也避免了跨窗口問題。當然IE彈窗中還是有Bug,不必管它了。 現在多少人還在用IE?多少人還在用彈窗?

              和Object.prototype.toString類似地,Function.prototype.toString也有類似功能, 不過它的this只能是Function,其他類型(例如基本數據類型)都會拋出異常。

              總結

              typeof只能檢測基本數據類型,對于null還有Bug;

              instanceof適用于檢測對象,它是基于原型鏈運作的;

              constructor指向的是最初創建者,而且容易偽造,不適合做類型判斷;

              toString適用于ECMA內置JavaScript類型(包括基本數據類型和內置對象)的類型判斷;

              基于引用判等的類型檢查都有跨窗口問題,比如instanceof和constructor。

              總之,如果你要判斷的是基本數據類型或JavaScript內置對象,使用toString; 如果要判斷的時自定義類型,請使用instanceof。

              有時Duck Typing的方式也非常可行,貌似已經成為了前端的慣例。 比如jQuery是這樣判斷一個Window的:

              isWindow: function(obj){

              return obj && typeof obj === 'object' && "setInterval" in obj;

              }

              另外DOM Element的類型檢測也可以通過上述的方法來完成,但沒有一種方法在任何瀏覽器上都可行。 DOM Element的類型檢測可以參見這篇文章:/pic/2011/01/28/checking-types-in-javascript/

              同時發表在:/pic/2015/09/18/js-type-checking.html

            【如何檢查JavaScript變量的類型】相關文章:

            PHP弱類型變量是如何實現的01-28

            Java 變量類型02-28

            C語言變量的類型12-10

            Java 變量類型介紹10-20

            PHP變量類型和整型類型細節02-05

            C語言指針變量的類型01-23

            Java的變量類型有哪些11-11

            Java數據類型以及變量的定義02-02

            C語言變量和數據類型09-12

                    <pre id="bbfd9"><del id="bbfd9"><dfn id="bbfd9"></dfn></del></pre>

                    <ruby id="bbfd9"></ruby><p id="bbfd9"><mark id="bbfd9"></mark></p>

                    <p id="bbfd9"></p>

                    <p id="bbfd9"><cite id="bbfd9"></cite></p>

                      <th id="bbfd9"><form id="bbfd9"><dl id="bbfd9"></dl></form></th>

                      <p id="bbfd9"><cite id="bbfd9"></cite></p><p id="bbfd9"></p>
                      <p id="bbfd9"><cite id="bbfd9"><progress id="bbfd9"></progress></cite></p>
                      飘沙影院