typeof的作用及用法


typeof的作用及用法

1.檢查一個變量是否存在,是否有值.

typeof在兩種情況下會返回"undefined":一個變量沒有被聲明的時候,和一個變量的值是undefined的時候.例如:

1.

  alert(typeof undeclaredVariable === "undefined");    // true

2.

  var declaredVariable;

  alert(typeof declaredVariable);    // 'undefined' 

  alert(typeof undefined );     // 'undefined'

 

還有其他辦法檢測某個值是否是undefined:

3.

   var value = undefined;

   alert(value === undefined );   //true


但這種方法如果使用在一個未聲明的變量上的時候,就會拋出異常,因為只有typeof才可以正常檢測未聲明的變量的同時還不報錯:

4.

  alert(undeclaredVariable === undefined);      //ReferenceError: undeclaredVariable is not defined

  alert( typeof undeclaredVariable === undefined);    //false

 

注意:未初始化的變量,沒有被傳入參數的形參,不存在的屬性,都不會出現上面的問題,因為它們總是可訪問的,值總是undefined:

5.

   var declaredVariable;

  declaredVariable === undefined         //true

  var aa = (function (x) { return x === undefined }())     // aa = true

  alert( ({}).foo === undefined );   //  true
譯者注:因此,如果想檢測一個可能沒有被聲明的全局變量是否存在,也可以使用 if(window.maybeUndeclaredVariable){}

 

2.判斷一個值不等於undefined也不等於null

問題:如果你想檢測一個值是否被定義過(值不是undefined也不是null),那么你就遇到了typeof最有名的一個怪異表現(被認為是一個bug):typeof null返回了"object":

  > typeof null 'object'
譯者注:這只能說是最初的JavaScript實現的bug,而現在標准就是這樣規范的.V8曾經修正並實現過typeof null === "null",但最終證明不可行.http://wiki.ecmascript.org/doku.php?id=harmony:typeof_null

(也可以理解為null是屬於object數據類型的一種特殊形式)

 

解決辦法: 不要使用typeof來做這項任務,用下面這樣的函數來代替:

  function isDefined(x) { return x !== null && x !== undefined; }
另一個可能性是引入一個“默認值運算符”,在myValue未定義的情況下,下面的表達式會返回defaultValue:

myValue ?? defaultValue
上面的表達式等價於:

  (myValue !== undefined && myValue !== null) ? myValue : defaultValue
又或者:

  myValue ??= defaultValue
其實是下面這條語句的簡化:

  myValue = myValue ?? defaultValue
當你訪問一個嵌套的屬性時,比如bar,你或許會需要這個運算符的幫助:

  obj.foo.bar
如果obj或者obj.foo是未定義的,上面的表達式會拋出異常.一個運算符.??可以讓上面的表達式在遍歷一層一層的屬性時,返回第一個遇到的值為undefined或null的屬性:

  obj.??foo.??bar
上面的表達式等價於:

  (obj === undefined || obj === null) ? obj : (obj.foo === undefined || obj.foo === null) ? obj.foo : obj.foo.bar

 

 

3.區分對象值和原始值

下面的函數用來檢測x是否是一個對象值:

  function isObject(x) { return (typeof x === "function" || (typeof x === "object" && x !== null)); }
問題: 上面的檢測比較復雜,是因為typeof把函數和對象看成是不同的類型,而且typeof null返回"object".

解決辦法: 下面的方法也經常用於檢測對象值:

  function isObject2(x) { return x === Object(x); }
警告:你也許認為這里可以使用instanceof Object來檢測,但是instanceof是通過使用使用一個對象的原型來判斷實例關系的,那么沒有原型的對象怎么辦呢:

  > var obj = Object.create(null);

  > Object.getPrototypeOf(obj) null
obj確實是一個對象,但它不是任何值的實例:

  > typeof obj 'object'

  > obj instanceof Object false
在實際中,你可能很少遇到這樣的對象,但它的確存在,而且有它的用途.

譯者注:Object.prototype就是一個默認存在的,沒有原型的對象

  >Object.getPrototypeOf(Object.prototype)null

  >typeof Object.prototype'object'

  >Object.prototype instanceof Object false

 

4.原始值的類型是什么?

typeof是最好的用來查看某個原始值的類型的方式.

  > typeof "abc" 'string'

  > typeof undefined 'undefined'
問題: 你必須知道typeof null的怪異表現.

  > typeof null // 要小心! 'object'
解決辦法: 下面的函數可以修復這個問題(只針對這個用例).

  function getPrimitiveTypeName(x) { var typeName = typeof x; switch(typeName) { case "undefined": case "boolean": case "number": case "string": return typeName; case "object": if (x === null) { return "null"; } default: // 前面的判斷都沒通過 throw new TypeError("參數不是一個原始值: "+x); } }

更好的解決辦法: 實現一個函數getTypeName(),除了可以返回原始值的的類型,還可以返回對象值的內部[[Class]]屬性.這里講了如何實現這個函數(譯者注:jQuery中的$.type就是這樣的實現)

 

5.某個值是否是函數

typeof可以用來檢測一個值是否是函數.

  > typeof function () {} 'function'

  >  typeof Object.prototype.toString 'function'

原則上說,instanceof Function也可以進行這種需求的檢測.乍一看,貌似寫法還更加優雅.但是,瀏覽器有一個怪癖:每一個框架和窗口都有它自己的全局變量.因此,如果你將某個框架中的對象傳到另一個框架中,instanceof就不能正常工作了,因為這兩個框架有着不同的構造函數.這就是為什么ECMAScript5中會有Array.isArray()方法的原因.如果有一個能夠跨框架的,用於檢查一個對象是否是給定的構造函數的實例的方法的話,那會很好.上述的getTypeName()是一個可用的變通方法,但也許還有一個更根本的解決方案.

 

6.綜述

下面提到的,應該是目前JavaScript中最迫切需要的,可以代替一些typeof目前職責的功能特性:

  isDefined() (比如Object.isDefined()): 可以作為一個函數或者一個運算符
  isObject()
  getTypeName()
能夠跨框架的,檢測一個對象是否是指定的構造函數的實例的機制
檢查某個變量是否已經被聲明這樣的需求,可能沒那么必要有自己的運算符.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM