当前位置: 首页 > news >正文

javascript类型判断

在ECMAScript中值分为原始类型和引用类型.

原始类型有五种分别为:Undefined, Null, Number, Boolean, String.

引用类型包括:Object, Function, Array, Date, RegExp等.

对于数据类型的坚持有几种方法,让我们由浅入深的分析下.

1. typeof是最弱的的一种检测方法

typeof运算符只返回number, string, boolean, undefined, object, function.对于基本数据类型检测还可以满足.但对于返回对象类型的就无从下手了.如:

typeof null、typeof {}、typeof window、typeof []、typeof new Date()都会返回Object.对于null可以用value === null来进行严格检测. 但对于其他

几种就不行了.所以这里仅给出基本数据类型的检测函数:

     function  type(o) { return  (o  ===   null ?   null  :  typeof (o)};
    document.write(type(
0 +   " , "   +  type( true +   " , "   +  type(undefined)  +  
    
" , "   +  type( null +   " , "   +  type(type));

 

2. 使用instanceof或者constructor来检测instanceof的检测原理为:运算符左侧对象的原型链是否和右侧对象的prototype属性是同一个对象。因此这就存在问题了,假如左右侧的对象不在一个页面中,这样他们的引用就不太可能是一个对象了。典型的示例就是在存在frame的页面中,如a.html通过iframe包含b.html,如果在a.html中定义var arr=[];然后再b.html中通过parent.arr instanceof Array就会返回false,因为parent.arr的原型链是和parent.Array对象的prototype属性引用的同一个对象,而和b.html中的Array的prototype属性完全没有关系。

我们看到了instanceof对于数组类型检测存在的局限性:必须在同一个页面中的对象才能正确检测。其实采用constructor属性来判断和instanceof的局限性是一样的,因为他们都是对比的对象引用是否一样。

所以JQ给了如下判断数组的方法:

     var  isArray  =   function (arr) {  return   !! arr  &&  arr.constructor  ==  Array}
    alert(isArray([
123 ]));
看似完美的方法,却产生了意外,那就是当左侧对象和右侧对象不在同一个页面中,那样原型链被打断了就无法判断.在FF下运行以下代码:
     var  isArray  =   function (arr) {  return   !! arr  &&  arr.constructor  ==  Array; }
    window.onload 
=   function (){
        
var  iframe  =  document.createElement( " iframe " );
        document.body.appendChild(iframe);
        
var  xArray  =  window.frames[window.frames.length  -   1 ].Array;
        
var  arr  =   new  xArray( 1 2 3 );
        alert(isArray(arr)); 
//  false
    }
3. 特性检测( Duck-typing )

采用简单的假设方式来做检测,如数组对象存在concat、splice、sort等相比其它对象特有的一些特性,因此可以通过简单判断对象是否有这些特性来进行检测。如下面的一些实现例子:

// prototype1.5的实现
function  isArray(object){
    
return  object  !=   null   &&   typeof  object  ===   " object "   &&
        
' splice '   in  object  &&   ' join '   in  object;
}

// Douglas Crockford在2003年提供的方式
typeof  myArray.sort  ==   ' function ' ;
这个方法虽然避免了2方法的问题,但由于Object的伪装性,缺点也显而易见.如:
var  myArray  =  { ' splice ' 1 ' join ' 2 ' sort ' function (){}};
alert(isArray(myArray));
alert(
typeof  myArray.sort  ==   ' function ' )
虽然是对象但可以伪装成数组的属性,而躲过检测.
4. 采用Object.prototype.toString.call(o)来检测
为什么要用Object.prototype.toString而不是Function.prototype.toString或者其它?这是和他们的toString解释方式有关系的。下面是ECMA中对Object.prototype.toString的解释:
Object.prototype.toString( )When the toString method is called, the following steps are taken: 1 . Get the [[Class]] property of  this  object. 2 . Compute a string value by concatenating the three strings “[object “, Result ( 1 ), and “]”. 3 . Return Result ( 2 )
其过程简单说来就是:1、获取对象的类名(对象类型)。2、然后将[object、获取的类名、]组合并返回。
ECMA中对Array有如下说明:
The [[Class]] property of the newly constructed object is set to “Array”.
因此我们用如下代码来检测数组:
     function  isArray(o){
        
return  Object.prototype.toString.call(o)  ===   ' [object Array] ' ;
    }
这是个完美的解决方案,当然对于Function, Date等也都适用.
最后给个综合的方法
     var  is  =  {
        types: [
" Array " " RegExp " " Date " " Number " " String " " Object " ]
    };
    
for ( var  i  =   0 ,c;c  =  is.types[i ++ ];){
        is[c] 
=  ( function (type){
            
return   function (obj){
                
return  Object.prototype.toString.call(obj)  ===   ' [object  '   +  type  + ' ] ' ;
            }
        })(c);
    }

    alert(is[
" Array " ]([ 1 , 2 , 3 ]));   // true
    alert(is[ " RegExp " ]( / [0-9] / ));  //  true
    alert(is[ " Number " ]( " str " ));    //  false
今天又追加个方法
var isArray = function(arr) { return Array.toString() == arr.constructor }

转载于:https://www.cnblogs.com/bluedream2009/archive/2009/07/25/1530649.html

相关文章:

  • SQL语句性能测试
  • C#中的预编译指令介绍
  • jQuery学习整理 (4) 事件与事件对象 (重点)
  • 导出sql脚本时的几个问题
  • 手机游戏量产引擎研发手记-导读
  • 2009-8-5 我的自省与收获
  • C#.NET描述arcobjects中的接口查询(QI)技术
  • 软件工程 之 学习C#前的总结~
  • [转]宝宝1岁内,各阶段动作发展
  • Page.RegisterStartupScript的使用方法
  • QQ2009性能优化测试版 会员补丁
  • CListCtrl使用技巧(1)
  • C Java PHP Perl Python的程序代码美化工具使用
  • FTP服务器搭建--虚拟多用户(vsftpd)
  • Http Handler 介绍
  • android 一些 utils
  • Docker入门(二) - Dockerfile
  • ESLint简单操作
  • JavaScript 一些 DOM 的知识点
  • js正则,这点儿就够用了
  • XML已死 ?
  • 阿里云应用高可用服务公测发布
  • 近期前端发展计划
  • 嵌入式文件系统
  • 如何设计一个比特币钱包服务
  • 如何使用Mybatis第三方插件--PageHelper实现分页操作
  • 如何邀请好友注册您的网站(模拟百度网盘)
  • 实现菜单下拉伸展折叠效果demo
  • 我有几个粽子,和一个故事
  • 用 Swift 编写面向协议的视图
  • LevelDB 入门 —— 全面了解 LevelDB 的功能特性
  • mysql面试题分组并合并列
  • 完善智慧办公建设,小熊U租获京东数千万元A+轮融资 ...
  • ​草莓熊python turtle绘图代码(玫瑰花版)附源代码
  • ###C语言程序设计-----C语言学习(3)#
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • #前后端分离# 头条发布系统
  • $ git push -u origin master 推送到远程库出错
  • (笔试题)合法字符串
  • (二)正点原子I.MX6ULL u-boot移植
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (附源码)ssm高校运动会管理系统 毕业设计 020419
  • (力扣题库)跳跃游戏II(c++)
  • (六)vue-router+UI组件库
  • (七)理解angular中的module和injector,即依赖注入
  • (一)硬件制作--从零开始自制linux掌上电脑(F1C200S) <嵌入式项目>
  • (转)h264中avc和flv数据的解析
  • (转)关于多人操作数据的处理策略
  • ***监测系统的构建(chkrootkit )
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .apk 成为历史!
  • .net core 6 集成 elasticsearch 并 使用分词器
  • .NET delegate 委托 、 Event 事件,接口回调
  • /*在DataTable中更新、删除数据*/
  • @RequestBody的使用