判断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 相关文章推荐
js 实现css风格选择器(压缩后2KB)
Jan 12 Javascript
DWR实现模拟Google搜索效果实现原理及代码
Jan 30 Javascript
讨论html与javascript在浏览器中的加载顺序问题
Nov 27 Javascript
RGB和YUV 多媒体编程基础详细介绍
Nov 04 Javascript
jQuery插件DataTable使用方法详解(.Net平台)
Dec 22 Javascript
vue轮播图插件vue-awesome-swiper
Nov 27 Javascript
nginx部署访问vue-cli搭建的项目的方法
Feb 12 Javascript
Angular5升级RxJS到5.5.3报错:EmptyError: no elements in sequence的解决方法
Apr 09 Javascript
js canvas实现橡皮擦效果
Dec 20 Javascript
vue中上传视频或图片或图片和文字一起到后端的解决方法
Dec 01 Javascript
js数组的基本使用总结
Jan 18 Javascript
uniapp引入支付宝原生扫码插件步骤详解
Jul 23 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
一个数据采集类
2007/02/14 PHP
php递归函数三种实现方法及如何实现数字累加
2015/08/07 PHP
PHP Curl模拟登录微信公众平台、新浪微博实例代码
2016/01/28 PHP
php实现获取近几日、月时间示例
2019/07/06 PHP
javascript自适应宽度的瀑布流实现思路
2013/02/20 Javascript
js 赋值包含单引号双引号问题的解决方法
2014/02/26 Javascript
使用BootStrap实现用户登录界面UI
2016/08/10 Javascript
js微信扫描二维码登录网站技术原理
2016/12/01 Javascript
js实现3D图片展示效果
2017/03/09 Javascript
详解ES6之用let声明变量以及let loop机制
2017/07/15 Javascript
Angularjs 1.3 中的$parse实例代码
2017/09/14 Javascript
vue系列之requireJs中引入vue-router的方法
2018/07/18 Javascript
jQuery pagination分页示例详解
2018/10/23 jQuery
Vue安装浏览器开发工具的步骤详解
2019/05/12 Javascript
基于vue实现一个神奇的动态按钮效果
2019/05/15 Javascript
Vue+element 解决浏览器自动填充记住的账号密码问题
2019/06/11 Javascript
vue 判断页面是首次进入还是再次刷新的实例
2020/11/05 Javascript
python进阶教程之动态类型详解
2014/08/30 Python
Python+微信接口实现运维报警
2016/08/27 Python
Python模块、包(Package)概念与用法分析
2019/05/31 Python
Python连接Mysql进行增删改查的示例代码
2020/08/03 Python
python 如何引入协程和原理分析
2020/11/30 Python
留学自荐信
2013/10/10 职场文书
民间借贷协议书范本
2014/10/01 职场文书
离婚协议书怎样才有法律效力
2014/10/10 职场文书
违纪学生保证书
2015/02/27 职场文书
争先创优个人总结
2015/03/04 职场文书
2015年财务经理工作总结
2015/05/13 职场文书
亮剑观后感600字
2015/06/05 职场文书
追讨欠款律师函
2015/06/24 职场文书
导游词之韩国济州岛
2019/10/28 职场文书
详解用Python把PDF转为Word方法总结
2021/04/27 Python
python实现三阶魔方还原的示例代码
2021/04/28 Python
html+css实现环绕倒影加载特效
2021/07/07 HTML / CSS
Oracle数据库中通用的函数实例详解
2022/03/25 Oracle
微信小程序实现轮播图指示器
2022/06/25 Javascript