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

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 中测试通过
// Numbers
console.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'); // 不要这样使用!// Strings
console.log(typeof "" === 'string');
console.log(typeof "bla" === 'string');
console.log(typeof (typeof 1) === 'string'); // console.log(typeof返回的肯定是一个字符串
console.log(typeof String("abc") === 'string'); // 不要这样使用!// Booleans
console.log(typeof true === 'boolean');
console.log(typeof false === 'boolean');
console.log(typeof Boolean(true) === 'boolean'); // 不要这样使用!// Symbols
console.log(typeof Symbol() === 'symbol');
console.log(typeof Symbol('foo') === 'symbol');
console.log(typeof Symbol.iterator === 'symbol');// Undefined
console.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);//false
console.log(a.constructor);//function Object() { [native code] }
console.log(typeof A);//function Object() { [native code] }console.log(a.constructor === b.constructor);//false
console.log(b.constructor);//function Function() { [native code] }console.log(a instanceof A);//false
console.log(b instanceof A);//true

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

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

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

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

再看一个复杂的用法

 console.log(Object instanceof Object);//true console.log(Function instanceof Function);//true console.log(Number instanceof Number);//false console.log(String instanceof String);//false console.log(Function instanceof Object);//true console.log(Foo instanceof Function);//true console.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); //true
console.log(ObjectL.__proto__.__proto__ === Object.prototype);//true

Function instanceof Function

FunctionL = Function, FunctionR = Function;
console.log(FunctionL instanceof FunctionR);//true
console.log(FunctionL.__proto__ === Function.prototype); //true

Foo instanceof Foo

function Foo(){}
var foo = new Foo();
FooL = Foo, FooR = Foo;
console.log(FooL instanceof FooR);//false
console.log(FooL.__proto__ === Function.prototype );//true
console.log(FooL.__proto__.__proto__ === Object.prototype );//true
console.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);//true console.log(foo instanceof Boo);//false console.log(foo.isInstanceOf(Aoo));//true console.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 中测试通过
// Numbers
console.log(37 instanceof Number);//false
console.log( 3.14 instanceof Number);.//false
console.log( Math.LN2 instanceof Number);//false
console.log( Infinity instanceof Number);//false
console.log( NaN instanceof Number); // false尽管NaN是"Not-A-Number"的缩写,意思是"不是一个数字"
console.log( Number(1) instanceof Number); // false不要这样使用!// Strings
console.log( "" instanceof String);// false
console.log( "bla" instanceof String);// false
console.log( ( 1) instanceof String); //  falseconsole.log(返回的肯定是一个字符串
console.log( String("abc") instanceof String); // false 不要这样使用!// Booleans
console.log( true instanceof Boolean);// false
console.log( false instanceof Boolean);// false
console.log( Boolean(true) instanceof Boolean); //false 不要这样使用!// Symbols
console.log( Symbol() instanceof Symbol);// false
console.log( Symbol("foo") instanceof Symbol);// false
console.log( Symbol.iterator instanceof Symbol);// false// Undefined
var blabla;
//console.log( undefined instanceof Undefined);// Uncaught ReferenceError: Undefined is not defined
//console.log( blabla instanceof Undefined); // Uncaught ReferenceError: Undefined is not defined
console.log( undefined instanceof Object);// false
console.log( blabla instanceof Object);// false// Objects 使用Array.isArray或者Object.prototype.toString.call方法可以从基本的对象中区分出数组类型
console.log( {a:1} instanceof Object);//true
console.log( [1, 2, 4] instanceof Object);//true
console.log( /^[a-zA-Z]{5,20}$/ instanceof Object);//true
console.log( {name:'wenzi', age:25} instanceof Object);//true
console.log( null === Object);//false// 下面的容易令人迷惑,不要这样使用!
console.log( new Boolean(true) instanceof Object);//true
console.log( new Number(1) instanceof Object);//true
console.log( new Date() instanceof Object);//true
console.log( new String("abc") instanceof Object);//true
console.log( new Error() instanceof Object);//true// 函数
console.log( function(){} instanceof Function );//true
console.log( Math.sin instanceof Function);//true

注意:undefined和null是检测的Object类型,因为js中没有UndefinedNull的这种全局类型,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); // false
console.log(John.constructor==Person);  // true

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

function Type() { };var types = [new Array,[],new Boolean,true,        // remains unchangednew Date,new Error,new Function,function(){},Math,  new Number,1,           // remains unchangednew 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]');//true
console.log(toString.call(new String) ==='[object String]');//true
console.log(toString.call(new Function) ==='[object Function]');//true
console.log(toString.call(Type) ==='[object Function]');//true
console.log(toString.call('str') ==='[object String]');//true
console.log(toString.call(Math) === '[object Math]');//true
console.log(toString.call(true) ==='[object Boolean]');//true
console.log(toString.call(/^[a-zA-Z]{5,20}$/) ==='[object RegExp]');//true
console.log(toString.call({name:'wenzi', age:25}) ==='[object Object]');//true
console.log(toString.call([1, 2, 3, 4]) ==='[object Array]');//true
//Since JavaScript 1.8.5
console.log(toString.call(undefined) === '[object Undefined]');//true
console.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实现的

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/instanceof

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor

http://www.ibm.com/developerworks/cn/web/1306_jiangjj_jsinstanceof/

http://segmentfault.com/q/1010000003872816?_ea=403162

http://www.ecma-international.org/ecma-262/5.1/#sec-11.8.6

转载于:https://www.cnblogs.com/chenpingzhao/p/4888800.html

Javascript中类型的判断相关推荐

  1. Python中类型最佳判断方法

    Python在定义变量的时候不用指明具体的的类型,解释器会在运行的时候会自动检查变量的类型,并根据需要进行隐式的类型转化,因为Python是动态语言,所以一般情况下是不推荐进行类型转化的. 比如进行& ...

  2. java中typeof_深入剖析JavaScript中的数据类型判断(typeof instanceof prototype.constructor)...

    关于JavaScript中的类型判断,我想大部分JavaScripter 都很清楚 typeof 和  instanceof,却很少有人知道 constructor,以及constructor与前面二 ...

  3. JavaScript中的数据类型判断

    typeof typeof 操作符返回一个字符串,表示未经计算的操作数的类型. 语法 typeof 运算符后接操作数: typeof operand typeof(operand) 参数 operan ...

  4. javascript中变量的判断

    相对于其它的编程语言来说,javascript为弱类型的,即变量不分类型,甚至不用定义就可以直接使用.这点跟linux 下的shell很像.但有两种情况容易混淆,一种是变量用var定义而没有赋值的情况 ...

  5. JavaScript中类型检测

    文章首发: http://www.cnblogs.com/sprying/p/4349426.html 本文罗列了一般Js类型检测的方法,是构建Js知识体系的一小块,这篇文章是我很早之前总结的. 一. ...

  6. 在javascript中,如何判断一个被多次encode 的url 已经被decode到原来的格式?

    % 而不能被无限次decodeURIComponent 可以用%来进行判断 转载于:https://www.cnblogs.com/zhouyideboke/p/11169705.html

  7. JavaScript中Object.prototype.toString方法的原理

    在JavaScript中,想要判断某个对象值属于哪种内置类型,最靠谱的做法就是通过Object.prototype.toString方法. <一>, ECMAScript 3  1. 在E ...

  8. 电话号码正则表达式 代码 javascript+html,JS正则表达式判断11位手机号码

    JavaScript中可以使用正则表达式var myreg=/^[1][3,4,5,7,8][0-9]{9}$/;来判断是否为11位有效电话号码. JavaScript中可以使用正则表达式判断是否为1 ...

  9. 创建健壮的isArray()函数(JavaScript中判断对象类型的种种方法)

    我们知道,JavaScript中检测对象类型的运算符有:typeof.instanceof,还有对象的constructor属性: 1) typeof 运算符 typeof 是一元运算符,返回结果是一 ...

最新文章

  1. 200多位专家热议“智慧城市” 建议尽快完善标准体系
  2. linux ssh远程登录 配置文件 sshd_config 介绍
  3. php long2ip,php ip2long和long2ip函数实现
  4. sql server死锁的查询和解除
  5. 使用python打印数字三角形_11届省赛python试题 H: 数字三角形
  6. BufferedInputStream的read()方法源码解析
  7. 矩量法 惠更斯 matlab,矩量法分析振子天线粗细对天线的影响毕业设计(论文).doc...
  8. 解决ffmpeg中的时间戳同步问题
  9. 雷军说小米综合净利润率永远不超过5%,玺哥相信他是真心的!
  10. pytorch创建datset
  11. GDAL源码剖析(四)之命令行程序说明一
  12. 【java学习之路】(数据结构篇)002.栈和队列
  13. 几种排序算法的比较(冒泡、快速、Shell排序)
  14. 【转】Roberts 算子
  15. 快速明白ARCore + 上手
  16. 获取微信商户平台操作证书
  17. SAPnbsp;BORnbsp;--nbsp;…
  18. 配置IDEA/创建springboot+maven项目
  19. 计算机子网掩码作用,什么是子网掩码?子网掩码的作用是什么?
  20. 训练SSD时,viz报错

热门文章

  1. 删除出现次数最少字符串JAVA_牛客网——华为机试(题23:删除字符串中出现次数最少的字符)(Java)...
  2. 信安教程第二版-第15章网络安全主动防御技术与应用
  3. Android应用发布渠道汇总(更新中)
  4. requestmapping里面的参数_golang web开发——参数绑定(上)之用Go实现简单的Trie
  5. ES6-使用let关键字定义变量
  6. 25条div+CSS编程提醒及小技巧整理
  7. spring-bean(xml方式DI)
  8. python-day11-MYSQL 数据库及数据表
  9. tomcat 热部署、热加载 精析
  10. (转)python 搭建libsvm方法。python版本和libsvm版本匹配很重要!