判断数据类型的方法

一、五种方式,分别为 typeof、instanceof 、constructor、Array.isArray()、Object.prototype.toString.call()

typeof

一、通过 typeof操作符来判断一个值属于哪种基本类型,typeof只能区分值类型。

类型 结果
Number number
NaN
String string
Boolean boolean
Undefined undefined
Symbol symbol
Object object
null
Array
Function function

| 【示例】```javascript typeof’seymoe’// ‘string’ typeof true // ‘boolean’ typeof 10 // ‘number’ typeof Symbol() // ‘symbol’ typeof null // ‘object’ 无法判定是否为 null typeof undefined // ‘undefined’

typeof {} // ‘object’ typeof [] // ‘object’ typeof(() => {}) // ‘function’

  1. |
  2. | --- |
  3. 二、缺陷<br />1 如果使用 typeof null得到的结果是object<br />2、操作符对对象类型及其子类型,例如函数(可调用对象)、数组(有序索引对象)等进行判定,则除了函数都会得到 object 的结果。
  4. | 【示例】判断是否是引用类型```javascript
  5. function isObject(value) {
  6. const type = typeof value;
  7. return value != null && (type === 'object' || type === 'function');
  8. }

| | —- |

instanceof

一、通过 instanceof 操作符也可以对对象类型进行判定,其原理就是测试构造函数的prototype 是否出现在被检测对象的原型链上。

[] instanceof Array// true
({}) instanceof Object// true
(()=>{}) instanceof Function// true

二、复制代码注意:instanceof 也不是万能的。

| 【示例】```javascript let arr = [] let obj = {} arr instanceof Array// true arr instanceof Object// true obj instanceof Object// true obj instanceof Array// false

1、在这个例子中,arr 数组相当于 new Array() 出的一个实例,所以 arr.__proto__ === Array.prototype,又因为 Array属于 Object 子类型,即Array.prototype.__proto__ === Object.prototype,因此 Object 构造函数在 arr 的原型链上。所以 instanceof 仍然无法优雅的判断一个值到底属于数组还是普通对象。<br />2、还有一点需要说明下,有些开发者会说 Object.prototype.__proto__ === null,岂不是说 arr instanceof null 也应该为 true,这个语句其实会报错提示右侧参数应该为对象,这也印证 typeof null 的结果为 object 真的只是javascript中的一个bug 。 |
| --- |

<a name="nOKfA"></a>
### 关于简单数值类型的对象化(对象包装器)
一、JS规范要求: 

- 使用var num1=123; 这样的代码,直接返回基本数据类型,就是说返回的对象不是派生自Number和Object类型,用num1 instanceof Object测试为false;
- 使用new关键字创建则返回Number类型,例如var num2=new Number(123); num2 instanceof Number为true。

<a name="RC474"></a>
## constructor属性
一、JavaScript中,每个对象都有一个constructor属性,它引用了初始化该对象的构造函数,常用于判断未知对象的类型。如给定一个求知的值 通过typeof运算符来判断它是原始的值还是对象。如果是对象,就可以使用constructor属性来判断其类型。
<a name="YkyRU"></a>
## Array.isArray()
一、用来判断是否数组
<a name="Kzbmn"></a>
## (推荐):Object.prototype.toString() 
一、可以说是判定 JavaScript 中数据类型的终极解决方法了,具体用法请看以下代码:
```javascript
Object.prototype.toString.call({})              // '[object Object]'
Object.prototype.toString.call([])              // '[object Array]'
Object.prototype.toString.call(() => {})        // '[object Function]'
Object.prototype.toString.call('seymoe')        // '[object String]'
Object.prototype.toString.call(1)               // '[object Number]'
Object.prototype.toString.call(true)            // '[object Boolean]'
Object.prototype.toString.call(Symbol())        // '[object Symbol]'
Object.prototype.toString.call(null)            // '[object Null]'
Object.prototype.toString.call(undefined)       // '[object Undefined]'

Object.prototype.toString.call(newDate())      // '[object Date]'
Object.prototype.toString.call(Math)            // '[object Math]'
Object.prototype.toString.call(newSet())       // '[object Set]'
Object.prototype.toString.call(newWeakSet())   // '[object WeakSet]'
Object.prototype.toString.call(newMap())       // '[object Map]'
Object.prototype.toString.call(newWeakMap())   // '[object WeakMap]'

二、我们可以发现该方法在传入任何类型的值都能返回对应准确的对象类型。用法虽简单明了,但其中有几个点需要理解清楚:

  • 该方法本质就是依托Object.prototype.toString()方法得到对象内部属性 [[Class]]
  • 传入原始类型却能够判定出结果是因为对值进行了包装
  • null 和 undefined 能够输出结果是内部实现有做处理

三、对于类型判断,我们可以通过 Object.prototype.toString() 进行一个简单的封装,这样我们再判断类型的时候,直接使用 type 函数就可以了。

var type = function(data) {
  var toString = Object.prototype.toString;
  var dataType = toString
    .call(data)
    .replace(/\[object\s(.+)\]/, "$1")
    .toLowerCase()
  return dataType
};


类型判断

判断一个值到底是数组类型还是对象

一、3种方法:Array.isArray()、instanceof、Object.prototype.toString()

| 【示例】下面哪些方式在同一个窗口下能够检测一个js对象是数组类型?( )
A. Array.isArray()
B. instanceof
C. typeof
D. Object.prototype.toString.call()
答案:ABD
解析:
一、A选项:Array为js的原生对象,它有一个静态方法:Array.isArray(),能判断参数是否为数组```javascript let arr = [1, 2, 3]; Array.isArray(arr); // true

二、B选项:instanceof运算符返回布尔值,表示对象是否为某个构造函数的实例```javascript
let arr = [1, 2, 3];
arr instanceof Array; // true

三、C选项:
1、typeof能判断的类型有:number, string, boolean, symbol, undefined, function
2、object, array, null的变量都返回object
四、D选项:Object.prototype.toString()为Object对象的实例方法,默认情况下(即不重写该方法),返回参数的类型字符串```javascript // 基本类型 Object.prototype.toString.call(1); // [object Number] Object.prototype.toString.call(‘1’); // [object String] Object.prototype.toString.call(false); // [object Boolean] Object.prototype.toString.call(Symbol()); // [object Symbol] Object.prototype.toString.call(undefined); // [object Undefined] Object.prototype.toString.call(null); // [object Null] // 引用类型 Object.prototype.toString.call({a: 1}); // [object Object] Object.prototype.toString.call([1, 2, 3]); // [object Array] Object.prototype.toString.call(console.log); // [object Function]

后面直接使用slice(8, -1)直接取出类型```javascript
Object.prototype.toString.call(1).slice(8, -1); // 'Number'

| | —- |

Array.isArray()

一、Array.isArray 也可以判断传递参数是否是数组。
二、Array.isArray 是 ES 5.1 推出的,不支持 IE6~8,所以在使用的时候也应注意兼容问题。
1、出现不兼容问题解决办法

if (!Array.isArray) {
  Array.isArray = function(arg) {
    returnObject.prototype.toString.call(arg) === '[object Array]';
  };
}

判断字符串是否为json格式

一、如果JSON.parse能够转换成功,并且转换后的类型为Object且不等于null,那么这个字符串就是JSON格式的字符串

function isJSON(str) {
    if (typeof str == 'string') {
        try {
            var obj=JSON.parse(str);
            if(typeof obj == 'object' && obj ){
                return true;
            }else{
                return false;
            }

        } catch(e) {
            console.log('error:'+str+'!!!'+e);
            return false;
        }
    }
    console.log('It is not a string!')
}