前言:

随着编程实践的增加,慢慢发现关于数据类型的检测至关重要。我认为程序就是为了处理数据和展示数据。所以,数据的检测对于编程来说也至关重要。因为只有符合我们预期的输入,才可能产生正确的输出。众所周知,JavaScript是弱类型语言,这带来很多便利的同时,也带来了不少问题。为了减少编程实践中在变量判断方面出现的问题,我们需要对不确定的变量进行检测,以保证处理符合预期的数据。本文是对数据检测的总结。

1.检测原始值

ECMAScript 有 5 种原始类型(primitive type),即 Undefined、Null、Boolean、Number 和 String。对于原始值,我们可以使用typeof来检测。

 // 检测字符串
typeof "str" // 返回"string" // 检测数字
typeof 123 // 返回"number" // 检测布尔值
typeof true // 返回"boolean" // 检测undefined
typeof undefined // 返回"undefined" // 检测null
typeof null // 返回"object"

typeof运算符有个很独特的地方就是,当我们检测一个未声明的变量时也不会报错。未定义的变量和undefined的变量通过typeof检测都将返回“undefined”。

还有就是当我们用typeof检测null变量时,返回的是“object”而不是“null”。null一般是不用于检测语句的,简单地和null比较通常不会包含足够的信息以判断值的类型是否合法。但,当所期望的值确定是null,则可以和null直接比较(===和!==)。

2.检测引用值

引用值也称为对象,在js中除了原始值之外的值都是引用,如Object、Function、Array、String、Boolean、Number、Date等。由于使用typeof检测引用类型时,返回的是“object”,我们并不能真正的获得引用类型的详细信息。而instanceof运算符可以解决这个问题,instanceof 运算符与 typeof 运算符相似,用于识别正在处理的对象的类型。与 typeof 方法不同的是,instanceof 方法要求开发者明确地确认对象为某特定类型。基本用法为:

 value instanceof constructor

其含义是判断一个value是否为constructor对象的实例,如果是则返回true,否则返回false。

instanceof并不仅仅止步于检测构造这个对象的构造器,它还会沿着原型链进行检测。示例如下:

 var now = new Date();

 console.log(now instanceof Date);  // 输出:true
console.log(now instanceof Object); // 输出:true

在默认情况下,每个对象都继承自Object,因此每个对象的 value instanceof Object都会返回true,使用这个方法来判断对象是否属于某个特定类型的做法并非最佳。

instanceof运算符也可以用来检测自定义类型,示例如下:

 function BasicType() {
this.property=true; this.getBasicValue = function(){
return this.property;
};
} function NewType() {
this.subproperty=false;
} NewType.prototype = new BasicType();
var test = new NewType(); console.log(test instanceof NewType); // 输出:true
console.log(test instanceof BasicType); // 输出:true
console.log(test instanceof Object); // 输出:true

在JavaScript中检测自定义类型时,最好的做法就是使用instanceof运算符,这也是唯一的方法。

3.检测属性

另外一种用到null(以及undefined)的场景是当检测一个属性是否在对象中存在时,比如:

 // 不好的写法:检测假值
if (object[propertyName]) {
// code
} // 不好的写法:和null比较
if (object[propertyName] != null) {
// code
} // 不好的写法:和undefined比较
if (object[propertyName] != undefined) {
// code
}

在上例中,实际上是通过给定的属性名来检测属性的值,而非判断属性是否存在,因为当属性值为假值时结果超出我们的预期,比如0、""、false、null和undefined时。如果我们要检测的属性值为null或者undefined时,以上是哪个判断都会出错。

判断属性是否存在的最好方法是使用in运算符。in运算符只会判断属性存在与否,而不管属性值,这样就避免了上面问题的产生。

 var object = {
count: 0,
name: null
}; // 好的写法
if ("count" in object) {
// 执行代码
}; // 不好的写法:检测假值
if (object["count"]) {
// 不执行代码
}; // 好的写法
if ("name" in object) {
// 执行代码
}; // 不好的写法:检测是否为null
if (object["name"] != null) {
// 不执行代码
};

但还有一点需要注意,in运算符也会检测原型链上的所有属性,无论是实例上还是继承对象的原型上具有目标属性,都会返回true。如果需要检测对象的某个属性是否存在,则需要使用hasOwnProperty()方法。所有继承自Object的JS对象都有这个方法,如果实例中包含这个属性则返回true(如果这个属性只存在在原型中则返回false)。

然而,在IE8以及更早版本的IE中,DOM对象并非继承自Object,也就不包含hasOwnProperty()方法。我们在使用hasOwnProperty()方法时,应该先检测是否存在这个方法。

 var object = {
count = 0,
name = null
}; // 对于所有的非DOM对象来说,这是最好的实现
if (Object.hasOwnProperty("name")) {
// 执行代码
} // 对于所有不确定是否为DOM的对象来说,应该这样实现
if ("hasOwnProperty" in Object && Object.hasOwnProperty("name")) {
// 执行代码
}

不管在任何情况下检测属性的存在性,最好使用in运算符或者hasOwnProperty(),这样可以避免很多bug。

JavaScript数据检测的更多相关文章

  1. javascript的数据检测总结

    目录 javaScript的数据检测 1.typeof 2.instanceof 3.constructor 4.Object.prototype.toString.call()--------- 一 ...

  2. 谈谈JavaScript类型检测

      javascript内置的类型检测机制并非完全可靠.比如typeof操作符,并不能准确的判断数据是哪个类型,比如:数组和对象就不能通过typeof来区分. typeof [] ==="o ...

  3. JavaScript功能检测技术和函数构造

    Javascript与很多编程语言不同,它不能够控制其运行环境.再写php代码时,只要在服务器端部署了正确的版本,那么程序就绝对能够运行,对于其他python或ruby后端语言来说,也不存在什么灰色区 ...

  4. javascript 中检测数据类型的方法

    typeof 检测数据类型 javascript 中检测数据类型有好几种,其中最简单的一种是 typeof 方式.typeof 方法返回的结果是一个字符串.typeof 的用法如下: typeof v ...

  5. 什么才是正确的javascript数组检测方式

    前面的话 对于确定某个对象是不是数组,一直是数组的一个经典问题.本文专门将该问题择出来,介绍什么才是正确的javascript数组检测方式 typeof 首先,使用最常用的类型检测工具——typeof ...

  6. JavaScript 数据验证类

    JavaScript 数据验证类 /* JavaScript:验证类 author:杨波 date:20160323 1.用户名验证 2.密码验证 3.重复密码验证 4.邮箱验证 5.手机号验证 6. ...

  7. 第一百一十二节,JavaScript浏览器检测

    JavaScript浏览器检测 学习要点: 1.navigator对象 2.客户端检测 由于每个浏览器都具有自己独到的扩展,所以在开发阶段来判断浏览器是一个非常重要的步骤.虽然浏览器开发商在公共接口方 ...

  8. JavaScript数据类型检测 数组(Array)检测方式

    前言 对于确定某个对象是不是数组,一直是数组的一个经典问题.本文专门将该问题择出来,介绍什么才是正确的javascript数组检测方式 typeof 首先,使用最常用的类型检测工具--typeof运算 ...

  9. 【HANA系列】SAP HANA XS使用JavaScript数据交互详解

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA XS使用Jav ...

随机推荐

  1. 设计模式 (一)——策略模式(Strategy,行为型)

    1.概述 使用设计模式可以提高代码的可复用性.可扩充性和可维护性.策略模式(Strategy Pattern)属于行为型模式,其做法是将类所需的行为或者算法一个个封装成单独的类,并将其作为类的数据成员 ...

  2. WEB入门.六 盒子模型

    学习内容 CSS盒子模型 盒子之间的关系 页面元素定位 能力目标 理解盒子模型 理解内容与表现分离的优点 理解并掌握盒子之间的关系 理解并掌握绝对定位与相对定位的用法 本章简介 上一章节中已经讲解了页 ...

  3. Centos最小化安装后还需要安装的软件包收集

    自己也是初学,只是记录一下自己使用的时候需要安装的包: 1. yum install -y make wget mlocate net-tools 2. yum install -y gcc open ...

  4. git<撤销本地修改与回退版本>

    1. 使用 git checkout 撤销本地修改 即放弃对本地已修改但尚未提交的文件的修改,还原其到未修改前的状态. 注意: 已 add/ commit 的文件不适用个方法,应该用本文提到的第二种方 ...

  5. 主角场景Shader效果:遮挡透明

    基本原理:被遮挡的部分关闭深度写入, 显示透明效果:未被遮挡的部分不关闭深度测试,显示正常贴图效果,即使用两个Pass即可. Pass1:关闭深度写入(ZWrite Off),深度测试渲染较远的物体, ...

  6. SSH项目整合

    其实框架的整合无非就是jar包和配置文件: struts2.spring.Hibernate这三个框架,分清楚什么作用就好配置了. jar包我们就不说了,这里看下配置文件吧: struts.xml: ...

  7. 如何在servlet的监听器中使用spring容器的bean

    另外补充下:在web Server容器中,无论是Servlet,Filter,还是Listener都不是Spring容器管理的,因此我们都无法在这些类中直接使用Spring注解的方式来注入我们需要的对 ...

  8. bzoj 4919 [Lydsy1706月赛]大根堆 set启发式合并+LIS

    4919: [Lydsy1706月赛]大根堆 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 599  Solved: 260[Submit][Stat ...

  9. Python面向对象补充以及异常处理

    面向对象相关内容 一.isinstance(obj, cls) 检查是否obj是否是类 cls 的对象 class Foo(object): pass obj = Foo() isinstance(o ...

  10. OpenStack安装部署(二)

    中文文档:http://docs.openstack.org/mitaka/zh_CN/install-guide-rdo/提示:这个中文文档是直接翻译过来的,所以会有很多不通顺的地方. 服务介绍 M ...