判断js中各种数据的类型方法之typeof与0bject.prototype.toString讲解


Posted in Javascript onNovember 07, 2013

1、typeof(param) 返回param的类型(string)

这种方法是JS中的定义的全局方法,也是编译者们最常用的方法,优点就是使用简单、好记,缺点是不能很好的判断object、null、array、regexp和自定义对象。

示例代码:

var str='str';
var arr=['1','2'];
var num=1;
var bool=true;
var obj={name:'test'};
var nullObj=null;
var undefinedObj=undefined;
var reg=/reg/;
function fn(){
    alert('this is a function');
}
function User(name){
    this.name=name;
}
var user=new User('user');
console.log(typeof(str));
console.log(typeof(arr));
console.log(typeof(num));
console.log(typeof(bool));
console.log(typeof(obj));
console.log(typeof(nullObj));
console.log(typeof(undefinedObj));
console.log(typeof(reg));
console.log(typeof(fn));
console.log(typeof(user));

结果为:
string
object
number
boolean
object
object
undefined
object
function
object

2、Object.prototype.toString().call(param) 返回param的类型(string,格式是[object class])

这个方法能支持绝大多数类型的判断,jquery封装的类型判断就用的这个方法。可能有些人看起来有点迷茫,我来给大家分解一下。

1)call(param)函数

a.fun().call(b)的意思在js中是指,让对象b来代替a,然后执行a的fun函数,写个例子:

function Class1() 
{ 
    this.name = "class1"; 
    this.showNam = function() 
    { 
        alert(this.name); 
    } 
} 
function Class2() 
{ 
    this.name = "class2"; 
} 
var c1 = new Class1(); 
var c2 = new Class2(); 
c1.showNam.call(c2);

运行结果,输出的为class2,而不是class1,这就相当于是方法继承。
所以,Object.prototype.toString().call(param)的意思其实就是,param.prototype.toString(),那么我们为什么不直接写param.prototype.toString(),而是用call()绕一下呢,下面请看2来了解。

2)Object.prototype.toString()

Object是个什么东东呢?,Script56.chm(就是M$官方教程)上说:Obect提供所有 JScript对象通用的功能,其实Object就是所有js对象的祖先,是一个概念,js中的所有对象就是Object的实例,然后不同的对象重写自己独立的方法。而prototype,大家就没必要追究太深了,它就是返回一个原型的引用,然可以可以动态的给原型添加方法和属性
一个小例子

function class(){
  this.name = "class";
  this.showName = function(){
    alert(this.name);
  }
}
var obj = new class();
obj.showName();
class.prototype.showNameContact = function(){
  alert("prototype test"+this.name);
}
obj.showNameContact();

那么就会分别输出 class和prototype test class,本来构造函数class() 里是没有定义showNameContact函数的,而通过prototype我们就可以给对象原型动态添加函数,new的示例中自然就会有了。所以Object.prototype.toString()的意思就是执行Object这个祖先中的toString方法。

那么toString()是干嘛的呢?很多js手册中对toString()函数是这样定义的:
toString() 方法可把一个逻辑值转换为字符串,并返回结果,语法为:booleanObject.toString()。刚才我说了,js中的对象都是继承的Object,这些对象都自定义的有函数或者重构了Object的部分函数,而且它们都对toString()函数进行了重写。所以我们不能想1中直接写param.prototype.toString()这样就执行的是param自己重写后的toString()函数了。

好了,到关键的时刻了,toString()到底是干嘛的呢,有什么作用呢?

在ES3中,Object.prototype.toString方法的规范如下:

Object.prototype.toString()

在toString方法被调用时,会执行下面的操作步骤:

1. 获取this对象的[[Class]]属性的值.

2. 计算出三个字符串"[object ", 第一步的操作结果Result(1), 以及 "]"连接后的新字符串.

3. 返回第二步的操作结果Result(2).

在ES3中,规范文档并没有总结出[[class]]内部属性一共有几种,不过我们可以自己统计一下,原生对象的[[class]]内部属性的值一共有10种.分别是:"Array", "Boolean", "Date", "Error", "Function", "Math", "Number", "Object","RegExp", "String".所以Object.prototype.toString()的输出结果就是这种格式的字符串[object Array],[object Boolean]。

在ES5.1中,除了规范写的更详细一些以外,Object.prototype.toString方法和[[class]]内部属性的定义上也有一些变化,Object.prototype.toString方法的规范如下:

Object.prototype.toString ( )
在toString方法被调用时,会执行下面的操作步骤:

1 如果this的值为undefined,则返回"[object Undefined]".
2 如果this的值为null,则返回"[object Null]".
3 让O成为调用ToObject(this)的结果.
4 让class成为O的内部属性[[Class]]的值.
5 返回三个字符串"[object ", class, 以及 "]"连接后的新字符串.

可以看出,比ES3多了1,2,3步.第1,2步属于新规则,比较特殊,因为"Undefined"和"Null"并不属于[[class]]属性的值。经统计,可返回的类型有"Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", "String"比ES3多了2种分别是arguments对象的[[class]]成了"Arguments",而不是以前的"Object",还有就是多个了全局对象JSON,它的[[class]]值为"JSON"。

最后的最后提醒大家,Object.prototype.toString().call(param)返回的[object class]中class首字母是大写,像JSON这种甚至都是大写,所以,大家判断的时候可以都转换成小写,以防出错,Object.prototype.toString().call(param).toLowerCase()即可。

Javascript 相关文章推荐
利用onresize使得div可以随着屏幕大小而自适应的代码
Jan 15 Javascript
JS实现遮罩层效果的简单实例
Nov 12 Javascript
JavaScript从数组中删除指定值元素的方法
Mar 18 Javascript
javascript拖拽应用实例(二)
Mar 25 Javascript
弹出遮罩层后禁止滚动效果【实现代码】
Apr 29 Javascript
js删除数组元素、清空数组的简单方法(必看)
Jul 27 Javascript
vue事件修饰符和按键修饰符用法总结
Jul 25 Javascript
快速解决vue-cli在ie9+中无效的问题
Sep 04 Javascript
vue-router 手势滑动触发返回功能
Sep 30 Javascript
详解webpack之图片引入-增强的file-loader:url-loader
Oct 08 Javascript
在vue项目中使用sass语法问题
Jul 18 Javascript
js实现鼠标拖拽div左右滑动
Jan 15 Javascript
addEventListener()第三个参数useCapture (Boolean)详细解析
Nov 07 #Javascript
zTree插件之单选下拉菜单实例代码
Nov 07 #Javascript
jQuery把表单元素变为json对象
Nov 06 #Javascript
JQuery插件开发示例代码
Nov 06 #Javascript
javascript实现yield的方法
Nov 06 #Javascript
Javascript事件实例详解
Nov 06 #Javascript
zTree插件之多选下拉菜单实例代码
Nov 06 #Javascript
You might like
phpmyadmin config.inc.php配置示例
2013/08/27 PHP
yii,CI,yaf框架+smarty模板使用方法
2015/12/29 PHP
PHP中的Trait 特性及作用
2016/04/03 PHP
Symfony查询方法实例小结
2017/06/28 PHP
在Laravel5中正确设置文件权限的方法
2019/05/22 PHP
使用Javascript和DOM Interfaces来处理HTML
2006/10/09 Javascript
Javascript 判断客户端浏览器类型代码
2010/03/01 Javascript
JQuery 动态扩展对象之另类视角
2010/05/25 Javascript
js操作时间(年-月-日 时-分-秒 星期几)
2010/06/20 Javascript
js中的scroll和offset 使用比较的实例与分析
2013/09/29 Javascript
NodeJS学习笔记之Http模块
2015/01/13 NodeJs
如何实现chrome浏览器关闭页面时弹出“确定要离开此面吗?”
2015/03/05 Javascript
EXT中单击button按钮grid添加一行(光标位置可设置)的实例代码
2016/06/02 Javascript
Javascript动画效果(3)
2016/10/11 Javascript
AngularJS入门教程之Cookies读写操作示例
2016/11/02 Javascript
基于JS分页控件实现简单美观仿淘宝分页按钮效果
2016/11/07 Javascript
Vue.js实战之组件之间的数据传递
2017/04/01 Javascript
详解Vue中状态管理Vuex
2017/05/11 Javascript
微信小程序 setData使用方法及常用错误解决办法
2017/05/11 Javascript
Node.JS中快速扫描端口并发现局域网内的Web服务器地址(80)
2017/09/18 Javascript
JavaScript字符串转数字的5种方法及遇到的坑
2018/07/16 Javascript
小程序click-scroll组件设计
2019/06/18 Javascript
js实现多图和单图上传显示
2019/12/18 Javascript
详解vue中v-on事件监听指令的基本用法
2020/07/22 Javascript
[46:55]完美世界DOTA2联赛决赛 FTD vs Phoenix 第三场 11.08
2020/11/11 DOTA
Python中使用Inotify监控文件实例
2015/02/14 Python
Python实现多并发访问网站功能示例
2017/06/19 Python
Python实现读取邮箱中的邮件功能示例【含文本及附件】
2017/08/05 Python
django 使用全局搜索功能的实例详解
2019/07/18 Python
Django rstful登陆认证并检查session是否过期代码实例
2019/08/13 Python
CSS3实现同时执行倾斜和旋转的动画效果
2016/10/27 HTML / CSS
英国最好的包装供应商:Priory Direct
2019/12/17 全球购物
渗透攻击的测试步骤
2014/06/07 面试题
小学生自我评价范文
2014/01/25 职场文书
正科级干部考察材料
2014/05/29 职场文书
争做文明公民倡议书
2019/06/24 职场文书