[尊重原创,转载地址:http://www.cnblogs.com/fool/archive/2010/10/07/javascrpt.html]
开门见山,我们先来看一下代码:
1 |
var is = function (obj,type) {
|
2 |
var toString = Object.prototype.toString;
|
3 |
var _baseTypes = { 'undefined' : 'undefined' , 'number' : 'number' , 'boolean' : 'boolean' , 'string' : 'string' };
|
4 |
return (_baseTypes[ typeof obj]===type)||
|
5 |
(type === "Null" && obj === null ) ||
|
6 |
(type=== 'Function' && "object" === typeof document.getElementById ?
|
7 |
/^\s*\bfunction\b/.test( "" + obj):toString.call(obj).slice(8,-1) === type)||
|
在讲解这个函数之前,让我们先来看一下javascript类型判断的几个关键:
typeof
typeof运算符,用于判断一个或值是哪种类型的。
由于Javascript语言的灵性性与执行环境的复杂性,typeof运算符并不能正确判断出所有的类型。但对于基本数据类型,typeof具有神奇的功效,正如在 is 函数中看到的那样,_baseTypes变量中定义了typeof可以正确识别的基本数据类型列表,其中键为类型名称,值为typeof运算结果。
instanceof
instanceof可以检测某个对象是不是另一个对象的实例。
new String('abc') instanceof String //true
instanceof还可以检测父类型。
3 |
Pig.prototype = new Animal();
|
4 |
alert( new Pig() instanceof Animal);
|
可以看出,instanceof不适合用来检测一个对象本身的类型。
Constructor
所有对象都拥有一个constructor属性,它指向该对象的构造函数。
对于复合数据类型,我们可以采用如下方式进行检测:
1 |
isArray: function (arr) {
|
2 |
return !!arr && arr.constructor == Array;
|
但是比较悲剧的是这种行为并不是确定的,在一些极其特殊的情况下,会产生意外的结果:
1 |
<div class= "cnblogs_Highlighter" ><pre class= "brush:javascript" > var iframe = document.createElement( 'iframe' );
|
2 |
document.body.appendChild(iframe); |
3 |
var xArray = window.frames[window.frames.length-1].Array;
|
4 |
var arr = new xArray(1, 2, 3);
|
5 |
alert(arr instanceof Array);
|
下面是Johg Resig 《pro javacript Techniques》书中的一张列表:
Duck Typing
在犀牛书里,提到一句老话:"如果走路像鸭子,叫声像鸭子,那他就是鸭子"。换而言之,对于Array来说,如果一个对象有splice和join属性,那它就是一个Array:
2 |
return o != null && typeof o === ‘object’ &&
|
3 |
'splice' in o && 'join' in o;
|
显然,鸭子检测很容易误把自造的天鹅也当成鸭子:
1 |
alert(isArray({ 'splice' : '' , 'join' : '' }));
|
注:buck typing并不关注于类型,它关注的是行为,它是实际作用是相互之间约定一种行为接口,好实现类似于多态的调用
Object.toString
ECMA-262中的解释:
Object.prototype.toString()
when the toString method is called,the following steps are taken:
1.get the [[Class]] property of this object //得到内部属性[[Class]]
2.conpute a string value by concatenating the three strings "[object",Result(1),and"]" //构造一个字符串类型似于[object xxx]
3.return results(2) //返回第2条的执行结果
注:[[Class]]为对象的内部属性,无法真接访问到
这样,就有了:
2 |
return Object.prototype.toString.call(o) === '[object Array]' ;
|
因为是字符串比较,也就解决了环境问题和语法灵活性所带来的变化,因此比较稳定。
好,讲到现在,想必大家对javascript类型判断应该有一个较为深入的理解,我想通过自已的能力,应该也可以写一个比较完善的类型判断函数,那下面就来看一下我是如何实现的。
1 |
var is = function (obj,type) {
|
2 |
var toString = Object.prototype.toString;
|
3 |
var _baseTypes = { 'undefined' : 'undefined' , 'number' : 'number' , 'boolean' : 'boolean' , 'string' : 'string' };
|
4 |
return (_baseTypes[ typeof obj]===type)||
|
5 |
(type === "Null" && obj === null ) ||
|
6 |
(type=== 'Function' && "object" === typeof document.getElementById ?
|
7 |
/^\s*\bfunction\b/.test( "" + obj):toString.call(obj).slice(8,-1) === type)||
|
因为考虑到实用性,这里是通过传入对象obj和期望类型type,返回boolean值,true为obj为type类型,false为obj不为type类型来实现的.
首先,var toString = Object.prototype.toString;这里保存了一份对Object的原生toString方法的引用,方便后面使用
var _baseTypes = {'undefined':'undefined','number':'number','boolean':'boolean','string':'string'};
这里保存了一份对于typeof可以检测出来的基本数据类型的对象列表,其键类型名称,值为typeof该类型的结果。
然后:进行类型的检测,返回结果。
(_baseTypes[typeof obj] === type) :检测是否为基本数据类型
(type === 'Null' && obj === null):
因为null实际上属于Object类型,因此typeof null 和Object.prototype.toString(null)返回的结果都为object和[Object object]
在实际需求中,我们通常希望将null单独列出来作为一种类型来进行判断
(type==='function'&&'object'===typeof document.getElementById?/^\s*\bfunction\b/.test(""+obj):toString.call(obj).slice(8,-1)===type)
这里实际上是在判断obj是否是一个函数,而IE6存在bug,无法正确识别getElementById这类函数,因此做了上些特殊的处理。
obj instanceof type:判断obj是否为type的实例
这里主要是来处理一引起特殊情况,如一些自定义对象的问题。
02 |
function SubArray() {}
|
03 |
SubArray.prototype = []; |
05 |
var toString = Object.prototype.toString;
|
06 |
alert(toString( new Animal()));
|
07 |
alert(toString( new SubArray()));
|
12 |
alert( new SubArray() instanceof Array);
|
13 |
alert( new Animal() instanceof Animal);
|
好,并不多了,最后我们来看一个测试结果:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>typecheck.html</title>
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="this is my page">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
<script type="text/javascript">
var is = function (obj,type) {
var toString = Object.prototype.toString;
var _baseTypes = {'undefined':'undefined','number':'number','boolean':'boolean','string':'string'};
return (_baseTypes[typeof obj]===type)||
(type === "Null" && obj === null) ||
(type==='Function'&&"object" === typeof document.getElementById ?
/^\s*\bfunction\b/.test("" + obj):toString.call(obj).slice(8,-1) === type)||
obj instanceof type;
};
window.onload = function(){
var msg = document.getElementById("msg");
function addMsg(m){
msg.innerHTML+=m+"<br />";
}
//判断基本数据类型
addMsg("1,number"+":"+is(1,'number'));
addMsg("abc,string"+":"+is("abc","string"));
addMsg("true,boolean"+":"+is(true,"boolean"));
addMsg("undefined,undefined"+":"+is(undefined,'undefined'));
//判断引用数据类型
addMsg("null,Null"+":"+is(null,"Null"));
addMsg("new String(''),String"+":"+is(new String(""),"String"));
addMsg("{},Object"+":"+is({},"Object"));
addMsg("[],Array"+":"+is([],"Array"));
addMsg("/foo/,RegExp"+":"+is(/foo/,"RegExp"));
try {0()} catch (e) {
addMsg("try/catch(e),Error"+":"+is(e,"Error"));
}
addMsg("new Date(),Date"+":"+is(new Date(),"Date"));
addMsg("new Number(123),Number"+":"+is(new Number(123),"Number"));
addMsg("new Boolean(true),Boolean"+":"+is(new Boolean(true),"Boolean"));
addMsg("function(){},Function"+":"+is(function(){},"Function"));
function SubArray() {}
SubArray.prototype = [];
addMsg("SubArray,Array"+":"+is(new SubArray(),Array));
}
</script>
</head>
<body>
<div id="msg"></div>
</body>
</html>
兼容判断类型列表:
基本数据类型 undefined,string,number,boolean
复合数据类型 Date,String,Boolean,Number,Object,Function,Array,RegExp,Error
其他 instanceof 的范畴
参考:
分享到:
相关推荐
JavaScript类型检测的方法实例教程 JavaScript是web前端广泛应用的语言之一,在网页应用制作、脚本制作、小程序等诸多领域具有不可替代的的地位。笔者学习了一端时间的前端,颇感JS知识点的繁碎,故将学习到的一些...
在javascript中,typeof 和 instanceof 是用来判断数据类型比较通用的两个方法,这篇文章的目的是通过对这两个方法介绍来分析其存在的不足并提出优化方案。 typeof ——————————————————————...
Javascript静态类型检测器 Flow 中文参考指南
以识别JavaScript是否为恶意代码及具体哪种恶意类型的方法并利用 识别恶意代码的方法实现了可实时检测网页代码的Chrome扩展工 具。具体成果有: 1)通过对数据集进行代码的特征分析,我们提出了使用协同训 练的方法来...
认识JavaScript的数据类型;学习目标;认识JavaScript的数据类型;... 数据类型检测;认识JavaScript的数据类型;认识JavaScript的数据类型; 数据类型转换;认识JavaScript的数据类型;认识JavaScript的数据类型;认识Jav
javascript中的数据类型检测方法详解.docx
在用javaScript编程的过程中,我们经常会遇到这样一个问题,就是需要检测一个数据或变量的类型,本篇文章主要介绍了在javaScript中检测数据类型的几种方式小结,有兴趣的可以了解一下。
javascript 检测浏览器类型和版本的代码.docx
JavaScript中如何检测数据类型?有四种检测的方式: typeof:检测数据类型的运算符 instanceof : 检测某个实例是否属于这个类(什么是类) constructor: 获取当前实例的构造器 Object.prototype.toString.call :...
主要介绍了javascript基本数据类型及类型检测常用方法,总结分析了javascript的基本数据类型与类型检测的常用操作方法,具有一定参考借鉴价值,需要的朋友可以参考下
JavaScript引擎JIT代码的类型混淆缺陷检测器.pdf
浏览器检测的多种方式;介绍了javascript中检测浏览器类型的不同方式
主要向大家分享了一段JavaScript实现数据类型检测的代码,附上参数说明和使用说明,希望小伙伴们能够喜欢
悟透JavaScript>>写得太传神,印象太深刻了】 二、javascript的数据类型检测 1、万能的typeof 我们先测试一下通过typeof来获取简单数据类型。什么也别说了,上代码是王道: 代码如下: // 获取变量obj的数据类型 ...
typeof操作符 介于JavaScript是松散类型的,因此需要有一种手段来检测给定变量的数据类型——typeof就是负责提供者方面信息的操作符。对一个值使用typeof操作符可能返回下列某个字符串: ● “undefined”——如果...
主要介绍了javascript中的数据类型检测方法,结合实例形式分析了javascript数据类型并总结分析了常见的数据类型检测操作技巧,需要的朋友可以参考下
JavaScript权威指南-第六版 弗拉纳根(David Flanagan)著 前言1 第1章 JavaScript概述5 1.1 JavaScript语言核心8 ... 6.4 检测属性128 6.5 枚举属性130 6.6 属性getter和setter132 6.7 属性的特性134
介于JavaScript是松散类型的,因此需要有一种手段来检测给定变量的数据类型——typeof就是负责提供者方面信息的操作符。对一个值使用typeof操作符可能返回下列某个字符串: ● “undefined”——如果这个值未定义...