码迷,mamicode.com
首页 > 编程语言 > 详细

Javascript数据类型检测

时间:2016-03-17 19:29:30      阅读:299      评论:0      收藏:0      [点我收藏+]

标签:

Javascript有5种简单数据类型和一种复杂数据类型

  • 基本数据类型:String,Boolean,Number,Undefined, Null
  • 引用数据类型:Object(Array,Date,RegExp,Function)

1.typeof操作符

要检测一个变量是不是基本数据类型, typeof 操作符是最佳的工具。

  1. var s = "Nicholas";
  2. var b = true;
  3. var i = 22;
  4. var u;
  5. var n = null;
  6. var o = new Object();
  7. alert(typeof s); //string
  8. alert(typeof i); //number
  9. alert(typeof b); //boolean
  10. alert(typeof u); //undefined
  11. alert(typeof n); //object
  12. alert(typeof o); //object


但是从上面的执行结果可以看到,如果变量的值是一个对象或 null,则 typeof 操作符会像例子中所示的那样返回"object" ,那么问题来了,如何检测Null呢? 如果想将null和对象区分开,则必须进行显示检查

  1. function getType(obj) {
  2. return (obj === null) ? "null" : typeof (obj);
  3. }

2.instanceof 操作符
虽然在检测基本数据类型时 typeof 是非常得力的助手,但在检测引用类型的值时,这个操作符的用处不大。 通常, 我们并不是想知道某个值是对象,而是想知道它是什么类型的对象。为此, ECMAScript提供了 instanceof 操作符,其语法如下所示:
  1. result = variable instanceof constructor

如果变量是给定引用类型(根据它的原型链来识别)的实例,那么instanceof 操作符就会返回 true。请看下面的例子:
  1. alert(person instanceof Object); // 变量 person 是 Object 吗?
  2. alert(colors instanceof Array); // 变量 colors 是 Array 吗?
  3. alert(pattern instanceof RegExp); // 变量 pattern 是 RegExp 吗?
不仅如此,对于自定义的对象,此方法仍然有效,请看下面的例子。
  1. function Animal() {
  2. }
  3. function Bird() {
  4. }
  5. Bird.prototype = new Animal();
  6. Bird.prototype.fly = function () {
  7. //do some thing
  8. alert(‘I can fly!‘);
  9. }
  10. var pigeon = new Bird();
  11. alert(pigeon instanceof Bird); //true 毫无疑问
  12. alert(pigeon instanceof Animal); //true 由于原型链的关系
  13. alert(pigeon instanceof Object); //true

 根据规定,所有引用类型的值都是 Object 的实例。因此,在检测一个引用类型值和 Object 构造函数时, instanceof 操作符始终会返回 true。当然,如果使用 instanceof 操作符检测基本类型的值,则该操作符始终会返回 false,因为基本类型不是对象。看似instanceof 操作符能完全解决检测对象类型的问题,实际应用中也确实够用的。但是instanceof仍然存在一个问题,它假定只有一个全局执行环境。以检测对象是否为数组类型为例, 如果网页中包含多个框架,那实际上就存在两个以上不同的全局执行环境,从而存在两个以上不同版本的 Array 构造函数。如果你从一个框架向另一个框架传入一个数组,那么传入的数组与在第二个框架中原生创建的数组分别具有各自不同的构造函数。
  1. var iframe = document.createElement(‘iframe‘);
  2. document.body.appendChild(iframe);
  3. xArray = window.frames[window.frames.length-1].Array;
  4. var arr = new Array("1","2","3","4","5");
  5. alert(arr instanceof Array); // false
由于每个iframe都有一套自己的执行环境,跨frame实例化的对象彼此是不共享原型链的,因此导致上述检测代码失效!为了解决这个问题, ECMAScript 5 新增了 Array.isArray() 方法。这个方法的目的是最终确定某个值到底是不是数组,而不管它是在哪个全局执行环境中创建的。我们仍以上面的例子说明
  1. var iframe = document.createElement(‘iframe‘);
  2. document.body.appendChild(iframe);
  3. xArray = window.frames[window.frames.length-1].Array;
  4. var arr = new xArray("1","2","3","4","5");
  5. alert(arr instanceof Array); // false
  6. alert(Array.isArray(arr));//true

说到数组类型,下面总结一下如何判断变量是否为数组类型?
  • 方法一
        判断其是否具有“数组性质”,如slice()方法。但是存在自己给该变量定义slice方法的情况,故有时会失效
  1. function isArray(object) {
  2. return object!= null && typeof object == "object" && ‘splice‘ in object && ‘join‘ in object;
  3. }
  4. var liar = { splice: 1, join: 2 };
  5. alert(isArray(liar));//true,成功骗过了检测方法

  • 方法二
       obj instanceof Array这个方法在前面已经介绍过了,也是不完美的。
  • 方法三
      使用上文所述新方法Array.isArray(),但是支持 Array.isArray() 方法的浏览器有 IE9+、 Firefox 4+、 Safari 5+、 Opera 10.5+和 Chrome。对于版本比较旧的浏览器此方法不被支持。
  • 方法四
 以上那些方法看上去无懈可击,但是终究会有些问题,接下来介绍的方法可以说是无懈可击了。
大家知道,在任何值上调用 Object 原生的 toString() 方法,都会返回一个[object NativeConstructorName] 格式的字符串。每个类在内部都有一个[[Class]] 属性,这个属性中就指定了上述字符串中的构造函数名。举个例子吧。
  1. var arr=[1,2,3,4];
  2. alert(Object.prototype.toString.call(arr)); //"[object Array]"
由于原生数组的构造函数名与全局作用域无关,因此使用 toString() 就能保证返回一致的值。利用这一点,可以创建如下函数用来检测变量是否是数组类型:
  1. function isArray(value){
  2. return Object.prototype.toString.call(value) == "[object Array]";
  3. }
同样,也可以基于这一思路来测试某个值是不是原生函数或正则表达式
  1. function isFunction(value){
  2. return Object.prototype.toString.call(value) == "[object Function]";
  3. }
  4. function isRegExp(value){
  5. return Object.prototype.toString.call(value) == "[object RegExp]";
  6. }
Object.prototpye.toString() 本身也可能会被修改。这里讨论的技巧假设 Object.prototpye.toString() 是未被修改过的原生版本。
参考:Javascript高级程序设计(第3版)
           Javascript权威指南(第六版)









Javascript数据类型检测

标签:

原文地址:http://www.cnblogs.com/star91/p/5288685.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!