谈谈前端JavaScript 类型判断typeof和instanceof的区别及一个类型判断Util的简单实现

  instanceof和typeof运算符都能用来判断一个变量是否为空或是什么类型。typeof用以获取一个变量的类型,typeof一般只能返回如下几个结果果:number, boolean, string, function, object, undefined。我们可以使用typeof来获取一个变量是否存在,如if(typeof a!=“undefined”){//TODO},对于Date, Array, Null等特殊对象使用typeof一律返回object,这正是typeof的局限性。instanceof用于判断一个变量是否某个对象的实例,如var a=new Array(); alert(a instanceof Array);会返回true,同时alert(a instanceof Object)也会返回true;这是因为Array是object的子类。

1、typeof运算符

  typeof是一元运算符,放在操作数前面,返回表示操作数类型的一个字符串。任意操作数在typeof运算后返回值如下:

操作数 xtypeof xexample
undefined“undefined”var a; typeof a; //undefiend
null“object”var a = null; typeof a; //object
true“boolean”var a = true; typeof a; //boolean
数字或NaN“number”var a = “12” - 0; typeof a; //number
任意字符串“string”var a = 12 + “”; typeof a; //string
任意函数“function”var a = function(){}; function b(){};
typeof a; typeof b;//function function
任意内置对象“object”var a = new Date, b = new Array(1);
typeof a; type b; //object object

  通过上表我们可以看出typeof返回4类值:

  • 原始值:string, number, boolean
  • undefined
  • function
  • object:Date, Array等

注意function其实是object的一种,但是typeof返回function而不是object,需要注意,原因可以简单理解为:function是可执行的,根据ECMAScript3规范,对于所有内置可执行对象,typeof运算符一律返回"function"。

typeof运算对于判断操作数是原始值类型还是对象类型,尤其判断变量是否定义过非常有用,但是对于判断具体是Date还是Array还是其它就无能为力啦,需要instanceof运算符或其它技术手段实现。

2、instanceof运算符

  instanceof运算符希望左操作数是一个对象,右操作数标识对象类型的类。如果左侧对象是右侧类的实例,则返回true,否则返回false。通俗点理解就是:instanceof判断一个对象是否为某一数据类型,或一个变量是否为一个对象的实例。看个案例:

var d = new Date;
d instanceof Date;		//true
d instanceof Object;		//true, 所有对象都是object的实例
d instanceof Number;		//false
var a = [1,2,3];
a instanceof Array;		//true
a instanceof Object;		//true, 所有数组都是对象
a instanceof RegExp;		//false

  instanceof工作机制基于JavaScript原型链,类似Java继承关系。为了计算表达式o instanceof f,首先计算f.prototype,然后在o的原型链中查找f.prototype,如果找到,那么o是f的一个实例,表达式返回true。如果f.prototype不在o的原型链中,那么o就不是f的一个实例,表达式返回false。
判断:o.proto.proto…会不会等于f.prototype, 看个案例:

function C(){} 
function D(){}

var o = new C(); 
console.log('o instanceof C: ', o instanceof C); 	// true, o.__proto__ == C.prototype
console.log('o instanceof D: ', o instanceof D); 	// false, D.prototype不在o的原型链上 
console.log('o instanceof Object: ', o instanceof Object); 	// true, o.__proto__.__proto__ == Object.prototype
console.log(C.prototype instanceof Object) 			// true, C.prototype.__proto__ = Object.prototype

C.prototype = {}; 
var o2 = new C(); 
console.log(o2 instanceof C); 		// true 
console.log("o instanceof C", o instanceof C);  //false, C.prototype指向了一个空对象,这个对象不在o的原型链上. 

D.prototype = new C();
var o3 = new D(); 
o3 instanceof D; 					// true, 
o3 instanceof C; 					// true, o3是D的实例,而D继承C

关于JavaScript原型、原型链、Constuctor等大家可以参考:
1)JS原型链简单图解
2)深入理解JavaScript系列(5):强大的原型和原型链
3)Js中Prototype、proto、Constructor、Object、Function关系介绍

3、类型判断TypeUtil的简单实现

我们可以通过Object.prototype.toString方法,判断某个对象值属于哪种内置类型,一个案例:

var TypeUtil = (function() {
  return {
    isString: function(str) {
      return Object.prototype.toString.call(str) === "[object String]";
    },
    isNumber: function(num) {
      return Object.prototype.toString.call(num) === "[object Number]";
    },
    isBoolean: function(flag) {
      return Object.prototype.toString.call(flag) === "[object Boolean]";
    },
    isFunc: function(fn) {
      return Object.prototype.toString.call(fn) === "[object Function]";
    },
    isArray: function(arr) {
      return Object.prototype.toString.call(arr) === "[object Array]";
    },
    isObject: function(obj) {
      return Object.prototype.toString.call(obj) === "[object Object]";
    }
  };
}());
console.log("TypeUtil.isString: ", TypeUtil.isString("1212")); //true
console.log("TypeUtil.isNumber: ", TypeUtil.isNumber(1212)); //true
console.log("TypeUtil.isBoolean: ", TypeUtil.isBoolean(true)); //true
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值