Javascript 中的數據類型判斷

(遷移自舊博客2017 09 25)
javascript

typeof


咱們常使用typeof來判斷數據類型,在常規場景中足以應付數據類型判斷的須要:

var obj = {
    name: 'zhangxiang'
    };
    function foo() {
        console.log('this is a function');
    }
    var arr = [1,2,3];
    console.log(typeof 1);  // number
    console.log(typeof '1');  //string
    console.log(typeof true);  //boolean
    console.log(typeof null); //object
    console.log(typeof undefined); //undefined
    console.log(typeof obj); //object
    console.log(typeof foo);  //function
    console.log(typeof arr);   //object

typeof能夠判斷全部js中的基本數據類型(Null,Undefined,Boolean,String,Number),雖然null使用typeof返回的是object,可是不影響它的基本使用。可是若是想要判斷array,null等,它就起不到做用了。
html

instanceof


instanceof運算符用來測試一個對象在其原型鏈中是否存在一個構造函數的prototype屬性。
語法:object instanceof constructor
其實它適合於判斷自定義的類實例對象,而不是用來判斷原生的數據類型。

// a.html
    <script>
      var a = [1,2,3];
    </script>
    //main.html
    <iframe src="a.html"></iframe>
    <script>
      var frame = window.frame[0];
      var a = frame.a;
      console.log(a instanceof Array);  // false
      console.log(a.contructor === Array);  //false
      console.log(a instanceof frame.Array); // true
    </script>

iframe 之間不會共享原型鏈, 由於他們有獨立的執行環境, 因此 frame a 中的數組 a 不會是本執行環境的實例對象。 經過特性嗅探一樣不靠譜, 像經過 contructor,sort, slice 等等的特有的數組(或者其餘數據類型)方法或屬性, 萬一對象中也有 sort, slice 屬性, 就會發生誤判。因此最靠譜的方法是使用 Object.prototype.toString 方法。
java

Object.prototype.toString


使用Object.prototype.toString方法,能夠獲取到變量的準確類型。

function foo(){};
    Object.prototype.toString.call(1);  '[object Number]'
    Object.prototype.toString.call('1'); '[object String]'
    Object.prototype.toString.call(NaN); '[object Number]'
    Object.prototype.toString.call(foo);  '[object Function]'
    Object.prototype.toString.call([1,2,3]); '[object Array]'
    Object.prototype.toString.call(undefined); '[object Undefined]'
    Object.prototype.toString.call(null); '[object Null]'
    Object.prototype.toString.call(true); '[object Boolean]'

Object.prototype.toString 的原理是當調用的時候, 就取值內部的 [[Class]] 屬性值, 而後拼接成 '[object ' + [[Class]] + ']' 這樣的字符串並返回. 而後咱們使用 call 方法來獲取任何值的數據類型。
node

有用的數據類型判斷函數


isArray polyfill


isArray 是數組類型內置的數據類型判斷函數, 可是會有兼容性問題, 因此模擬 underscore 中的寫法以下:

isArray = Array.isArray || function(array){
  return Object.prototype.toString.call(array) === '[object Array]';
}

isNaN polyfill

判斷一個數是否是 NaN 不能單純地使用 === 這樣來判斷, 由於 NaN 不與任何數相等, 包括自身, 因此:數組

isNaN: function(value){
  return isNumber(value) && isNaN(value);
}

這裏的 isNumber 就是用上面所說的Object.prototype.toString進行判斷的,而後使用isNaN來判斷值,至於爲何須要在判斷 isNaN 以前須要判斷是否是 Number類型,這是由於NaN自己也是數字類型(Object.prototype.toString 可知), 在ES6的isNaN 中只有值爲數字類型使用NaN纔會返回 true, 這是爲了模擬 ES6 的 isNaN。
瀏覽器

判斷是不是 DOM 元素


在實際項目裏面, 有時或許咱們須要判斷是不是 DOM 元素對象, 那麼在判斷的時候利用的是 DOM 對象特有的 nodeType 屬性:
兼容作法原理是經過對象的 hasOwnProperty 方法來判斷對象是否擁有 callee 屬性從而判斷是否是 arguments 對象.
isElement: function(obj){
return !!(obj && obj.nodeType === 1);
}

判斷是不是對象

isObject: function(obj){
  var type = typeof obj;
  return type === 'function' || typeof === 'object' && obj !== null;
}

這裏的對象是狹義的, 是一般所指的 key-value 型的集合, 或者是 function 函數而且不爲 null。
函數

判斷是不是 arguments 對象 polyfill


判斷一個對象是否是 arguments 對象能夠經過 Object.prototype.toString 來判斷, 可是低版本的瀏覽器不支持, 他們返回的是 [object Object], 因此須要兼容:

isArguments: function(obj){
  return Object.prototype.toString.call(obj) === '[object Arguments]' || (obj != null && Object.hasOwnProperty.call(obj, 'callee'));
}

兼容作法原理是經過對象的 hasOwnProperty 方法來判斷對象是否擁有 callee 屬性從而判斷是否是 arguments 對象。測試

相關文章
相關標籤/搜索