基础类型: String、Number、Boolean、null、undefined、Symbol 存储在栈中,赋值变量和比较均为数据本身。 
引用类型:Object、Array、Map、Function 存储在堆中,使用new创建,赋值变量和比较均是内存地址。

1.typeof   基本数据类型

typeof 操作符返回一个字符串,表示未经计算的操作数的类型。

就这么几种类型:number、boolean、string、object、undefined、function、symbol。

typeof 用来判断基本数据类型,有两种写法:typeof xxx , typeof(xxx)

例如:

typeof 2 输出 'number' 
typeof NaN 输出 'number'
typeof null 输出 'object' 
typeof {} 输出 'object' 
typeof [] 输出 'object. 
typeof (function(){}) 输出 'function' 
typeof undefined 输出 'undefined' 
typeof '222' 输出 'string' 
typeof true 输出 'boolean'

2. instanceof    引用数据类型

instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。

判断已知实例对象是哪个构造类型/引用类型(类)。

涉及的构造函数有这些基础类型:String、Number、Boolean、Undefined、Null、Symbol;

复杂类型:Array,Object;

其他类型:Function、RegExp、Date。

语法:[对象] instanceof [构造函数]      同一个window下才会返回true

    var c= [1,2,3]; 
    var d = new Date(); 
    var e = function(){alert(111);}; 
    var f = function(){this.name="22";}; 
    console.log(c instanceof Array) //true
    console.log(d instanceof Date)  //true
    console.log(e instanceof Function) //true
    // console.log(f instanceof function ) //false
// 注意左侧必须是对象(object),如果不是,直接返回false,具体见基础类型。

 基础类型:

let num = 1
num instanceof Number // false

num = new Number(1)
num instanceof Number // true

3.constructor

根据对象的constructor判断,返回对创建此对象的数组函数的引用。

几乎可以判断基本数据类型和引用数据类型 

var c= [1,2,3]; 
var d = new Date(); 
var e = function(){alert(111);}; 

alert(c.constructor === Array) ----------> true 
alert(d.constructor === Date) -----------> true 
alert(e.constructor === Function) -------> true 

//注意: constructor 在类继承时会出错

4.Object.prototype.toString.call() 最准确的判断方式,强烈推荐

所有数据类型均可判断:Object.prototype.toString.call()
这是对象的一个原生原型扩展函数,用来更精确的区分数据类型(类)。

var gettype = Object.prototype.toString 
 
gettype.call('aaaa') 输出 [object String] 
gettype.call(2222) 输出 [object Number] 
gettype.call(true) 输出 [object Boolean] 
gettype.call(undefined) 输出 [object Undefined] 
gettype.call(null) 输出 [object Null] 
gettype.call({}) 输出 [object Object] 
gettype.call([]) 输出 [object Array] 
gettype.call(function(){}) 输出 [object Function]

其实js 里面还有好多类型判断 [object HTMLDivElement] div 对象 , [object HTMLBodyElement] body 对象 ,[object Document](IE)或者 [object HTMLDocument](firefox,google) ……各种dom节点的判断,这些东西在我们写插件的时候都会用到。

 可以封装的方法如下  :

var gettype=Object.prototype.toString 

var utility={ 
    isObj:function(o){ 
        return gettype.call(o)=="[object Object]"; 
    }, 
    isArray:function(o){ 
        return gettype.call(o)=="[object Array]"; 
    }, 
    isNULL:function(o){ 
        return gettype.call(o)=="[object Null]"; 
    }, 
    isDocument:function(){ 
        return gettype.call(o)=="[object Document]"|| [object HTMLDocument]; 
    } 
    ........ 
}

Object.prototype.toString() 的调用

对于 Object.prototype.toString() 方法,会返回一个形如 "[object XXX]" 的字符串。

如果对象的 toString() 方法未被重写,就会返回如上面形式的字符串。

({}).toString();     // => "[object Object]"
Math.toString();     // => "[object Math]"

但是,大多数对象,toString() 方法都是重写了的,这时,需要用 call() 或 Reflect.apply() 等方法来调用。 

var x = {
  toString() {
    return "X";
  },
};

x.toString();                                     // => "X"
Object.prototype.toString.call(x);                // => "[object Object]"
Reflect.apply(Object.prototype.toString, x, []);  // => "[object Object]"

原理
当调用一个方法时(这里指的是toString),函数执行上下文的this指向调用者(这里通过call来指定的)

  1. 该方法判断this是否为undefined或者null
  2. 如果是的话,直接返回[object Undefined]或者[object Null]
  3. 如果不是的话,就把this(可能是数字,可能是字符串,可能是函数,数组等)通通转化为对象O(toObject(this))
  4. 每一个对象都有一个自己的私有属性[[class]],是一个字符串值,表明了该对象的类型,该私有属性不能直接获取,只能通过Object.prototype.toString方法调用,所以toString方法获取到对象私有属性[[class]]的值class 后, 最后返回由"[object"+" "+"class"]"三个部分组成的字符串
function OPTSCType(typeObj) {
    // Object.prototype.toString.call(数据)  // 最后返回由"[object"+" "+"class"]"三个部分组成的字符串
    return Object.prototype.toString.call(typeObj).slice(Object.prototype.toString.call(typeObj).indexOf(' ') + 1, Object.prototype.toString.call(typeObj).length - 1);
}
// console.log(OPTSCType(undefined)); // Undefined

5.判断对象上是否具有某属性

ES6的 in(可以判断原型链上

  • in 运算符只能检查某个属性或方法是否可以被对象访问,不能检查是否是自身的属性和方法 
  • in 是用来判断对象或者数组中是否存在某个值的。我们先来看一下用in如何判断对象里是否有某个值。
let obj={
    a:'muzidigbig',
    b:'木子大大'
}
console.log('a' in obj);  //true

数组判断

以前会使用length属性进行判断,为0表示没有数组元素。但是这并不准确,或者说真实开发中有弊端。

let arr=[,,,,,];
console.log(0 in arr); //false
 
let arr1=['muzidigbig','木子大大',,];
console.log(2 in arr1);  // false
console.log(1 in arr1);  // true

hasOwnProperty

检查**对象自身**中是否含有该属性/方法,如果有返回 true

        function Monster(name, age, car) {
            this.name = name;
            this.age = age;
            this.car = car;
        }
        var niu = new Monster('niu', 29, 'biShui');

        Monster.prototype.hobby = '吃肉';

        // 考察 age
        console.log('hobby' in niu);//true
        console.log(niu.hasOwnProperty('hobby'));//false

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐