首頁  >  文章  >  web前端  >  如何取得javascript變數的類型

如何取得javascript變數的類型

青灯夜游
青灯夜游原創
2021-10-28 17:47:048267瀏覽

取得javascript變數類型的方法:1、使用typeof操作符,語法「typeof 變數」;2、使用jQuery的「$.type()」方法;3、透過建構函數來取得類型。

如何取得javascript變數的類型

本教學操作環境:windows7系統、javascript1.8.5&&jquery1.10.0版、Dell G3電腦。

在JavaScript中,如何準確取得變數的型別名稱是一個經常使用的問題.

但是常常不能取得到變數的精確名稱,或必須使用jQuery 中的方法,這裡我透過typeof ,jQuery.type 和透過建構函式來取得變數型別這三種方法詳細介紹一遍.

希望可以對你提供幫助.

看到題目的第一眼,有些同學可能會想到typeof 運算子.


使用typeof 取得基本的型別

在JavaScript語言中,給出了使用typeof 運算子來取得基本的型別名稱.(注意不是基本型別)

這是typeof 的全部用法

01-typeof.htm

console.log('typeof of 10 ~~~~' +typeof 10);
console.log('typeof of "a" ~~~~' +typeof 'a');
console.log('typeof of true ~~~~' +typeof true);
console.log('typeof of {} ~~~~' +typeof {});
console.log('typeof of /123/ ~~~~' +typeof /123/);
console.log('typeof of function(){} ~~~~' +typeof function(){});
console.log('typeof of undefined ~~~~' +typeof undefined);
console.log('typeof of null ~~~~' +typeof null);

這是結果

#按照上面的列印結果,總結出下面要注意的幾點

  • #typeof (引用型別) 除了函數, 都是'object',例如typeof /123/

  • typeof null 為'object'

  • typeof undefined 為'undefined',通常, 如果使用兩等號, null = = undefined 為真.

  • 轉換為數字的常見用法"10"-0, 如果沒有轉換成功,返回NaN,由於NaN 的一個特性: NaN != NaN,故判斷轉換成功與否的常見做法: (這也是我參見jQuery的源碼發現的,jQuery源碼讀100遍都不為過)
    ("10x" - 0) == ("10x" - 0 ); // 結果為假!

#使用jQuery中的方法$.type()

#現在看看jQuery是怎麼做的

// 先申明一个对象,目的是用来做映射
var class2type = {};
// 申明一个core_toString() 的方法,得到最原始的toString() 方法,因为在很多对象中,toStrintg() 已经被重写 
var core_toString() = class2type.toString;
// 这里为 toStrintg() 后的结果和类型名做一个映射,申明一个core_toString() 后的结果,而值就是类型名
jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
    class2type[ "[object " + name + "]" ] = name.toLowerCase();
});

因為Object.prototype.toString() 方法呼叫結果如下

var core_toString = {}.toString;
console.log( core_toString.call(1) );
console.log( core_toString.call("11") );
console.log( core_toString.call(/123/) );
console.log( core_toString.call({}) );
console.log( core_toString.call(function(){}) );
console.log( core_toString.call([]) );
console.log( core_toString.call(true) );
console.log( core_toString.call(new Date()) );
console.log( core_toString.call(new Error() ));
console.log( core_toString.call(null) );
console.log( core_toString.call(undefined) );
console.log( String(null) );
console.log( String(undefined) );

##上面的列印結果與

class2type[ "[object " + name + "]" ] = name.toLowerCase();
不謀而合!

這是jQuery.type 的核心方法

type: function( obj ) {
    if ( obj == null ) {
        return String( obj );
    }
    // Support: Safari <= 5.1 (functionish RegExp)
    return typeof obj === "object" || typeof obj === "function" ?
        class2type[ core_toString.call(obj) ] || "object" :
        typeof obj;
},

注意,為什麼把null 或者undefined 單獨討論呢,因為在一些版本瀏覽器中


console.log(core_toString.call(null));
console.log(core_toString.call(undefined));

這是會報錯的!

如果是物件類型,另:由於在一些低版本的瀏覽器中,typeof /123/ 會回傳的是"function" 而不是"object",所以這裡要判斷是否是函數,要明白這裡的 

typeof obj === function 不是為了函數討論的,因為函數本身就可以透過typeof 來得到型別.

typeof obj === "object" || typeof obj === "function" ?
        class2type[ core_toString.call(obj) ]

就直接回傳class2type 中鍵值對的結果,,如果不是,那麼一定就是基本型別, 透過typeof 就可以啦.

class2type[ core_toString.call(obj) ] || "object" :
// 这是防止一些未知情况的,如果未取到,就返回object

但是 

jQuery.type 有一個很大的缺陷

這是一個自訂類型

function Person(){
   this.name = &#39;pawn&#39;;
}
var p = Person.toString();

// 注意,這裡會列印[object Object],透過上面的方法,無法得到精確的自訂類型

這也是它的一個大缺陷了!

#下面,我們透過建構函式的方式來取得精確型別

#透過建構子來取得型別

在理解這個方法之前,需要先理解兩個點

prorotype 原型屬性

我們知道,任何物件或函數都直接或間接的繼承自Object 或Function, (其實最終Function 是繼承自Object 的,這屬於原型鏈的知識了)。那麼,任何一個物件都有原型物件__proto__ (這個物件只在chrome 和firefox 暴露,但是在其他瀏覽器中也是存在的),這個原型物件就是這個物件的建構函式的原型屬性(這裡可能有點繞) .

由於任何函數都具有原型屬性prototype,並且這個原型屬性具有一個預設屬性constructor,它是這個函數的引用,看下面的程式碼

  function Person(){
      this.name = &#39;pawn&#39;;
  }
  console.log(Person.prototype.constructor === Person);

#發現,這兩個東西其實一個東西

但是,在某些情況下,需要這麼寫

  function Person(){
      this.name = &#39;pawn&#39;;
  }
  Person.protype = {
      XX: ... ,
      xx: ... ,
      ...
  }

這麼做,就會覆蓋原本的protype 方法,那麼construcor 就不存在了,這是,必須要顯示的申明這個物件

  Person.protype = {
      construction: Person,
      XX: ... ,
      xx: ... ,
      ...
  }

在jQuery的中,就是這麼做的,

  jQuery.fn = jQuery.prototype = {
    constructor: jQuery,
    init: function( selector, context, rootjQuery ) {
        var match, elem;

關於jQuery物件封裝的方式也是非常值得研究


    Function.prototype.toString()

注意,這裡已經不是熟悉[object Object],而是已經重寫了.

也就是,如果调用一个函数的toString() 方法.那么就会打印这个函数的函数体.


好了,经过上面两个步骤,你明白我要做什么了吗?

如何通过构造函数来获得变量的类型?

判断是否是基本类型

   var getType = function(obj){
       if(obj == null){
          return String(obj);
       }
       if(typeof obj === &#39;object&#39; || typeof obj === &#39;fucntion&#39;){
           ...
       }else{
           // 如果不是引用类型,那么就是基本类型
           return typeof obj
       }
   }

如果是对象或者函数类型

   function Person(){
       this.name = &#39;pawn&#39;;
   }
   var p = new Person();
   console.log(p.constructor);

现在要做的事 : 如何将Person 提取出来呢?
毋庸置疑,字符串切割那一套肯定可以办到,但是太 low 啦!
这里,我使用正则将Person提取出来

 var regex = /function\s(.+?)\(/
   function Person(){
    this.name = &#39;pawn&#39;;
   }
   var p = new Person();
   var c = p.constructor
   var regex = /function\s(.+?)\(/;
   console.log(&#39;|&#39; + regex.exec(c)[1] + &#39;|&#39;);

使用name

其实,除了上面的正则,每个函数还有一个name属性,返回函数名,但是ie8 是不支持的.

因此上面的代码可以写为:

var getType = function(obj){
    if(obj == null){
        return String(obj);
    }
    if(typeof obj === &#39;object&#39; || typeof obj === &#39;function&#39;){ 
        var constructor = obj.constructor;
        if(constructor && constructor.name){
            return constructor.name;
        }
        var regex = /function\s(.+?)\(/;
        return regex.exec(c)[1];
    }else{
        // 如果不是引用类型,那么就是基本;类型
        return typeof obj;
    }
};

但是上面的代码太丑啦,将其简化

简化

var getType = function(obj){
    if(obj == null){
        return String(obj);
    }
    if(typeof obj === &#39;object&#39; || typeof obj === &#39;function&#39;){ 
        return obj.constructor && obj.constructor.name.toLowerCase() || 
          /function\s(.+?)\(/.exec(obj.constructor)[1].toLowerCase();
    }else{
        // 如果不是引用类型,那么就是基本类型
        return typeof obj;
    }
};

还是比较麻烦,继续简化

var getType = function(obj){
    if(obj == null){
       return String(obj);
    }
    return typeof obj === &#39;object&#39; || typeof obj === &#39;function&#39; ?
      obj.constructor && obj.constructor.name && obj.constructor.name.toLowerCase() ||
          /function\s(.+?)\(/.exec(obj.constructor)[1].toLowerCase():
      typeof obj;
};

好了,已经全部弄完了,写个代码测试一下:

function Person(){
    this.name = &#39;pawn&#39;;
}
var p = new Person();

console.log(getType(p));
console.log(getType(1));
console.log(getType("a"));
console.log(getType(false));
console.log(getType(/123/));
console.log(getType({}));
console.log(getType(function(){}));
console.log(getType(new Date()));
console.log(getType(new Error()));
console.log(getType( null));
console.log(getType( undefined));

【推荐学习:javascript高级教程

以上是如何取得javascript變數的類型的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn