简单谈谈Javascript中类型的判断

 更新时间:2015年10月21日 21:47  点击:2953

数据类型的判断有这么几种方式

1、一元运算符 typeOf

2、关系运算符 instanceof

3、constructor 属性

4、prototype属性

一、typeof

typeof的返回值有以下几种

类型 结构
Undefined "undefined"
Null "object" (见下方)
布尔值 "boolean"
数值 "number"
字符串 "string"
Symbol (ECMAScript 6 新增) "symbol"
宿主对象(JS环境提供的,比如浏览器) Implementation-dependent
函数对象 (implements [[Call]] in ECMA-262 terms) "function"
任何其他对象 "object"

简单粗暴的方法,直接看代码

// 以下代码在版本 Google Chrome 45.0.2454.101 m 中测试通过// Numbersconsole.log(typeof 37 === 'number');console.log(typeof 3.14 === 'number');console.log(typeof Math.LN2 === 'number');console.log(typeof Infinity === 'number');console.log(typeof NaN === 'number'); // 尽管NaN是"Not-A-Number"的缩写,意思是"不是一个数字"console.log(typeof Number(1) === 'number'); // 不要这样使用! // Stringsconsole.log(typeof "" === 'string');console.log(typeof "bla" === 'string');console.log(typeof (typeof 1) === 'string'); // console.log(typeof返回的肯定是一个字符串console.log(typeof String("abc") === 'string'); // 不要这样使用! // Booleansconsole.log(typeof true === 'boolean');console.log(typeof false === 'boolean');console.log(typeof Boolean(true) === 'boolean'); // 不要这样使用! // Symbolsconsole.log(typeof Symbol() === 'symbol');console.log(typeof Symbol('foo') === 'symbol');console.log(typeof Symbol.iterator === 'symbol'); // Undefinedconsole.log(typeof undefined === 'undefined');console.log(typeof blabla === 'undefined'); // 一个未定义的变量,或者一个定义了却未赋初值的变量 // Objects 使用Array.isArray或者Object.prototype.toString.call方法可以从基本的对象中区分出数组类型console.log(typeof {a:1} === 'object');console.log(typeof [1, 2, 4] === 'object');console.log(typeof /^[a-zA-Z]{5,20}$/ === 'object');console.log(typeof {name:'wenzi', age:25} === 'object');console.log(typeof null === 'object');//true // 下面的容易令人迷惑,不要这样使用!console.log(typeof new Boolean(true) === 'object');console.log(typeof new Number(1) === 'object');console.log(typeof new Date() === 'object');console.log(typeof new String("abc") === 'object');console.log(typeof new Error() === 'object'); // 函数console.log(typeof function(){} === 'function');console.log(typeof Math.sin === 'function');

typeof 只能检查出来以上7几种类型

二、instanceof

instanceof 运算符用于识别正在处理的对象的类型,要求开发者明确地确认对象为某特定类型

1、instanceof 和 constructor 没有关系

var A = function() {};A.prototype = {}; var B = {};console.log(A.constructor);//function Function() { [native code] }console.log(B.constructor);//function Object() { [native code] } var a = new A();A.prototype = {}; var b = new A();b.constructor = A.constructor; console.log(a.constructor === A);//falseconsole.log(a.constructor);//function Object() { [native code] }console.log(typeof A);//function Object() { [native code] } console.log(a.constructor === b.constructor);//falseconsole.log(b.constructor);//function Function() { [native code] } console.log(a instanceof A);//falseconsole.log(b instanceof A);//true

2、instanceof又叫关系运算符,可以用来判断某个构造函数的prototype属性是否存在另外一个要检测对象的原型链上

var str = new String("hello world");console.log(str instanceof String);//trueconsole.log(String instanceof Function);//trueconsole.log(str instanceof Function);//false

第三次输出为什么会返回false呢 ?原文地址:Javascript中一个关于instanceof的问题

//表达式一的指向console.log(str.__proto__ === String.prototype);//trueconsole.log(str instanceof String); //true //表达式二的指向console.log(String .__proto__ === Function.prototype);//trueconsole.log(String instanceof Function);//true //表达式三的指向console.log(str .__proto__ === String.prototype);//trueconsole.log(str .__proto__.__proto__ === String.prototype.__proto__);//trueconsole.log(str .__proto__.__proto__ === Object.prototype);//trueconsole.log(str .__proto__.__proto__.__proto__ === null);//trueconsole.log(str instanceof Object);//trueconsole.log(str instanceof Function);//false

 再看一个复杂的用法

console.log(Object instanceof Object);//trueconsole.log(Function instanceof Function);//trueconsole.log(Number instanceof Number);//falseconsole.log(String instanceof String);//false console.log(Function instanceof Object);//true console.log(Foo instanceof Function);//trueconsole.log(Foo instanceof Foo);//false

为什么,这是为什么呢,要搞明白以下含义

1、语言规范中是如何定义这个运算符的

2、JavaScript 原型继承机制

Object instanceof Object

// 为了方便表述,首先区分左侧表达式和右侧表达式ObjectL = Object, ObjectR = Object;console.log(ObjectL instanceof ObjectR);//true

 

// 下面根据规范逐步推演console.log(ObjectL.__proto__ === Function.prototype); //trueconsole.log(ObjectL.__proto__.__proto__ === Object.prototype);//true

Function instanceof Function

FunctionL = Function, FunctionR = Function;console.log(FunctionL instanceof FunctionR);//trueconsole.log(FunctionL.__proto__ === Function.prototype); //trueFoo instanceof Foofunction Foo(){}var foo = new Foo();FooL = Foo, FooR = Foo;console.log(FooL instanceof FooR);//falseconsole.log(FooL.__proto__ === Function.prototype );//trueconsole.log(FooL.__proto__.__proto__ === Object.prototype );//trueconsole.log(FooL.__proto__.__proto__.__proto__ === null );//true

 instanceof 在 Dojo 继承机制中的应用

在 JavaScript 中,是没有多重继承这个概念的,就像 Java 一样。但在 Dojo 中使用 declare 声明类时,是允许继承自多个类的

dojo.declare("Aoo",null,{});dojo.declare("Boo",null,{});dojo.declare("Foo",[Aoo,Boo],{}); var foo = new Foo();console.log(foo instanceof Aoo);//trueconsole.log(foo instanceof Boo);//false console.log(foo.isInstanceOf(Aoo));//trueconsole.log(foo.isInstanceOf(Boo));//true

instanceof和多全局对象(多个frame或多个window之间的交互)

在浏览器中,我们的脚本可能需要在多个窗口之间进行交互。多个窗口意味着多个全局环境,不同的全局环境拥有不同的全局对象,从而拥有不同的内置类型构造函数。这可能会引发一些问题。比如,表达式 [] instanceof window.frames[0].Array 会返回false,因为 Array.prototype !== window.frames[0].Array.prototype,因此你必须使用 Array.isArray(myObj) 或者Object.prototype.toString.call(myObj) === "[object Array]"来判断myObj是否是数组。

// 以下代码在版本 Google Chrome 45.0.2454.101 m 中测试通过// Numbersconsole.log(37 instanceof Number);//falseconsole.log( 3.14 instanceof Number);.//falseconsole.log( Math.LN2 instanceof Number);//falseconsole.log( Infinity instanceof Number);//falseconsole.log( NaN instanceof Number); // false尽管NaN是"Not-A-Number"的缩写,意思是"不是一个数字"console.log( Number(1) instanceof Number); // false不要这样使用! // Stringsconsole.log( "" instanceof String);// falseconsole.log( "bla" instanceof String);// falseconsole.log( ( 1) instanceof String); // falseconsole.log(返回的肯定是一个字符串console.log( String("abc") instanceof String); // false 不要这样使用! // Booleansconsole.log( true instanceof Boolean);// falseconsole.log( false instanceof Boolean);// falseconsole.log( Boolean(true) instanceof Boolean); //false 不要这样使用! // Symbolsconsole.log( Symbol() instanceof Symbol);// falseconsole.log( Symbol("foo") instanceof Symbol);// falseconsole.log( Symbol.iterator instanceof Symbol);// false // Undefinedvar blabla;//console.log( undefined instanceof Undefined);// Uncaught ReferenceError: Undefined is not defined//console.log( blabla instanceof Undefined); // Uncaught ReferenceError: Undefined is not definedconsole.log( undefined instanceof Object);// falseconsole.log( blabla instanceof Object);// false // Objects 使用Array.isArray或者Object.prototype.toString.call方法可以从基本的对象中区分出数组类型console.log( {a:1} instanceof Object);//trueconsole.log( [1, 2, 4] instanceof Object);//trueconsole.log( /^[a-zA-Z]{5,20}$/ instanceof Object);//trueconsole.log( {name:'wenzi', age:25} instanceof Object);//trueconsole.log( null === Object);//false // 下面的容易令人迷惑,不要这样使用!console.log( new Boolean(true) instanceof Object);//trueconsole.log( new Number(1) instanceof Object);//trueconsole.log( new Date() instanceof Object);//trueconsole.log( new String("abc") instanceof Object);//trueconsole.log( new Error() instanceof Object);//true // 函数console.log( function(){} instanceof Function );//trueconsole.log( Math.sin instanceof Function);//true

注意:undefined和null是检测的Object类型,因为js中没有Undefined和Null的这种全局类型,number, string和boolean无法检测出它的类型

三、constructor

在使用instanceof检测变量类型时,我们是检测不到number, 'string', bool的类型的。因此,我们需要换一种方式来解决这个问题

Object.prototype.constructor返回一个指向创建了该对象原型的函数引用。需要注意的是,该属性的值是那个函数本身,而不是一个包含函数名称的字符串。对于原始值(如1,true 或 "test"),该属性为只读,所有对象都会从它的原型上继承一个 constructor 属性

constructor本来是原型对象上的属性,指向构造函数。但是根据实例对象寻找属性的顺序,若实例对象上没有实例属性或方法时,就去原型链上寻找,因此,实例对象也是能使用constructor属性的

function Person(){ }var Tom = new Person(); console.log(Tom.constructor === Person);//true

不过要注意,constructor属性是可以被修改的,会导致检测出的结果不正确

function Person(){ }function Student(){ }Student.prototype = new Person();var John = new Student();console.log(John.constructor==Student); // falseconsole.log(John.constructor==Person); // true

改变这个对象的constructor属性的值

function Type() { }; var types = [  new Array,  [],  new Boolean,  true,    // remains unchanged  new Date,  new Error,  new Function,  function(){},  Math,   new Number,  1,      // remains unchanged  new Object,  {},  new RegExp,  /(?:)/,  new String,  "test"    // remains unchanged]; for(var i = 0; i < types.length; i++) {  types[i].constructor = Type;  types[i] = [ types[i].constructor, types[i] instanceof Type, types[i].toString() ];}; console.log( types.join("/n") );

除了undefined和null,其他类型的变量均能使用constructor判断出类型

四、万能的Object.prototype.toString.call

使用toString()方法来检测对象类型

function Type() { }; var toString = Object.prototype.toString;console.log(toString.call(new Date) === '[object Date]');//trueconsole.log(toString.call(new String) ==='[object String]');//trueconsole.log(toString.call(new Function) ==='[object Function]');//trueconsole.log(toString.call(Type) ==='[object Function]');//trueconsole.log(toString.call('str') ==='[object String]');//trueconsole.log(toString.call(Math) === '[object Math]');//trueconsole.log(toString.call(true) ==='[object Boolean]');//trueconsole.log(toString.call(/^[a-zA-Z]{5,20}$/) ==='[object RegExp]');//trueconsole.log(toString.call({name:'wenzi', age:25}) ==='[object Object]');//trueconsole.log(toString.call([1, 2, 3, 4]) ==='[object Array]');//true//Since JavaScript 1.8.5console.log(toString.call(undefined) === '[object Undefined]');//trueconsole.log(toString.call(null) === '[object Null]');//true

附上判断函数 Javascript中的数据类型知多少

五、jquery的实现  jquery: "1.8.2",

jquery中提供了一个$.type的接口,看看代码

var m = Object.prototype.toString //501行 E = {};//512行 isFunction: function(a) { //645行  return p.type(a) === "function"},isArray: Array.isArray || function(a) {  return p.type(a) === "array"},isWindow: function(a) {  return a != null && a == a.window},isNumeric: function(a) {  return !isNaN(parseFloat(a)) && isFinite(a)},type: function(a) {  return a == null ? String(a) : E[m.call(a)] || "object"},isPlainObject: function(a) {  if (!a || p.type(a) !== "object" || a.nodeType || p.isWindow(a))    return !1;  try {    if (a.constructor && !n.call(a, "constructor") && !n.call(a.constructor.prototype, "isPrototypeOf"))      return !1  } catch (c) {    return !1  }  var d;  for (d in a)    ;  return d === b || n.call(a, d)},isEmptyObject: function(a) {  var b;  for (b in a)    return !1;  return !0},

可以看出来,jquery中就是用Object.prototype.toString.call实现的

[!--infotagslink--]

相关文章

  • 使用PHP+JavaScript将HTML页面转换为图片的实例分享

    这篇文章主要介绍了使用PHP+JavaScript将HTML元素转换为图片的实例分享,文后结果的截图只能体现出替换的字体,也不能说将静态页面转为图片可以加快加载,只是这种做法比较interesting XD需要的朋友可以参考下...2016-04-19
  • 关于JavaScript中name的意义冲突示例介绍

    在昨天的《Javascript权威指南》学习笔记之十:ECMAScript 5 增强的对象模型一文中,对于一段代码的调试出现了一个奇怪现象,现将源代码贴在下面: 复制代码 代码如下: <script type="text/javascript"> function Person(){}...2014-05-31
  • C#和JavaScript实现交互的方法

    最近做一个小项目不可避免的需要前端脚本与后台进行交互。由于是在asp.net中实现,故问题演化成asp.net中jiavascript与后台c#如何进行交互。...2020-06-25
  • JavaScript判断浏览器及其版本信息

    本篇文章主要分享了通过window.navigator来判断浏览器及其版本信息的实例代码。具有一定的参考价值,下面跟着小编一起来看下吧...2017-01-23
  • javascript自定义的addClass()方法

    复制代码 代码如下: //element:需要添加新样式的元素,value:新的样式 function addClass(element, value ){ if (!element.className){ element.className = value; }else { newClassName = element.className; newClas...2014-05-31
  • JavaScript中的this关键字使用方法总结

    在javascritp中,不一定只有对象方法的上下文中才有this, 全局函数调用和其他的几种不同的上下文中也有this指代。 它可以是全局对象、当前对象或者任意对象,这完全取决于函数的调用方式。JavaScript 中函数的调用有以下...2015-03-15
  • 详解javascript数组去重问题

    首先,我想到的是另建一个结果数组,用来存储原始数组中不重复的数据。遍历原始数组依次跟结果数组中的元素进行比较,检测是否重复。于是乎,我写出了如下代码A: Array.prototype.clearRepetitionA = function(){ var resul...2015-11-08
  • JavaScript中逗号运算符介绍及使用示例

    有一道js面试题,题目是这样的:下列代码的执行结果是什么,为什么? 复制代码 代码如下: var i, j, k; for (i=0, j=0; i<10, j<6; i++, j++) { k = i+j; } document.write(k); 答案是显示10,这道题主要考察JavaScript的逗...2015-03-15
  • javascript的事件触发器介绍的实现

    事件触发器从字面意思上可以很好的理解,就是用来触发事件的,但是有些没有用过的朋友可能就会迷惑了,事件不是通常都由用户在页面上的实际操作来触发的吗?这个观点不完全正确,因为有些事件必须由程序来实现,如自定义事件,jQue...2014-06-07
  • Javascript类型转换的规则实例解析

    这篇文章主要介绍了Javascript类型转换的规则实例解析,涉及到javascript类型转换相关知识,对本文感兴趣的朋友一起学习吧...2016-02-27
  • ActiveX控件与Javascript之间的交互示例

    1、ActiveX向Javascript传参 复制代码 代码如下: <script language="javascript" for="objectname" event="fun1(arg)"> fun2(arg); </script> objectname为ActiveX控件名,通过<object>标签里的id属性设定,如下; 复制...2014-06-07
  • 详解JavaScript操作HTML DOM的基本方式

    通过 HTML DOM,可访问 JavaScript HTML 文档的所有元素。 HTML DOM (文档对象模型) 当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model)。 HTML DOM 模型被构造为对象的树: 通过可编程的对象模型,Java...2015-10-23
  • JavaScript获取浏览器信息的方法

    Window有navigator对象让我们得知浏览器的全部信息.我们可以利用一系列的API函数得知浏览器的信息.JavaScript代码如下:function message(){ txt = "<p>浏览器代码名: " + navigator.appCodeName + "</p>";txt+= "<p>...2015-11-24
  • JavaScript预解析,对象详解

    这篇文章主要介绍了JavaScript预解析,对象的的相关资料,小编觉得这篇文章写的还不错,需要的朋友可以参考下,希望能够给你带来帮助...2021-11-10
  • 学习JavaScript设计模式之装饰者模式

    这篇文章主要为大家介绍了JavaScript设计模式中的装饰者模式,对JavaScript设计模式感兴趣的小伙伴们可以参考一下...2016-01-21
  • 跟我学习javascript的最新标准ES6

    虽然ES6都还没真正发布,但已经有用ES6重写的程序了,各种关于ES789的提议已经开始了,这你敢信。潮流不是我等大众所能追赶的。潮流虽然太快,但我们不停下学习的步伐,就不会被潮流丢下的,下面来领略下ES6中新特性,一堵新生代JS...2015-11-24
  • javascript设计模式之解释器模式详解

    神马是“解释器模式”?先翻开《GOF》看看Definition:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。在开篇之前还是要科普几个概念: 抽象语法树: 解释器模式并未解释如...2014-06-07
  • 一个奇葩的最短的 IE 版本判断JS脚本

    使用 conditional comment 来判断 IE 的版本。嗯,是早早有人提出,但没有认真看代码。昨天刚好在看 CSS3 PIE 的时候看到,觉得是不是不靠谱。今天看到 Paul Irish 也提起,那么,推荐一下吧。这是作者博客上写的:复制代码 代码...2014-05-31
  • JavaScript学习笔记整理_setTimeout的应用

    下面小编就为大家带来一篇JavaScript学习笔记整理_setTimeout的应用。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2016-10-03
  • JavaScript操作URL的相关内容集锦

    ---恢复内容开始---1.location.href.....(1)self.loction.href="http://www.cnblogs.com/url" window.location.href="http://www.cnblogs.com/url" 以上两个用法相同均为在当前页面打开URL页面 (2)this.locati...2015-10-30