Javascript中类型的判断
数据类型的判断有这么几种方式
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中没有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); // false
console.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]');//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
Javascript中类型的判断的更多相关文章
- JavaScript中instanceof的判断依据
读jquery源码的时候,发现作者为了让创建jquery对象更容易使用了用函数返回对象的方法 jQuery = function( selector, context ) { return new j ...
- 关于javascript 里面类型的判断
javacript至今共有7中类型 Six data types that are primitives: Boolean Null Undefined Number String Symbol (n ...
- 在JavaScript中,如何判断数组是数组?
如果你没有注意过这个问题,那么这个标题应该会让你感到困惑,判断数据类型这么基础的问题能有什么坑呢? 少年,你不能太天真了,我们朝夕面对的这门语言,可是JavaScript呀,任何你觉得已经习以为常的东 ...
- JavaScript中准确的判断数据类型
在 ECMAScript 规范中,共定义了 7 种数据类型,分为基本类型和引用类型两大类. 其中: 基本类型:String.Number.Boolean.Symbol.Undefined.Null ...
- 深入剖析JavaScript中的数据类型判断(typeof instanceof prototype.constructor)
关于JavaScript中的类型判断,我想大部分JavaScripter 都很清楚 typeof 和 instanceof,却很少有人知道 constructor,以及constructor与前面二 ...
- Javascript中数组的判断方法
摘要: 1.数组检测的方法: 1) typeof . 2) instanceof . 3) constructor . 4) Object.prototype.toString. 5) Array.i ...
- javascript中的分支判断与循环
分支判断与循环 分支结构 单一选择结构(if) 二路选择结构(if/else) 内联三元运算符 ?: 多路选择结构(switch) var condition = true; if (conditio ...
- Javascript中类型: undefined, number ,string ,object ,boolean
var a1; var a2 = true;var a3 = 1;var a4 = "Hello";var a5 = new Object();var a6 = null;var ...
- JavaScript 中 if 条件判断
在JS中,If 除了能够判断bool的真假外,还能够判断一个变量是否有值. 下面的例子说明了JS中If的判断逻辑: 变量值 true '1' 1 '0' 'null' 2 '2' false 0 n ...
随机推荐
- IsPostback小结
这两天一直碰到它,却总是不明白,甚至一开始连回传都不知道是啥..现在终于理解了,分享给大家,当然,如有不妥之处,还请大家不吝指教! 解释 要想明白IsPostback,先来看看下面的这 ...
- libcurl HTTP POST请求向服务器发送json数据【转】
转载:http://blog.csdn.net/dgyanyong/article/details/14166217 转载:http://blog.csdn.net/th_gsb/article/de ...
- Direct I/O,Synchronous I/O的概念
Direct I/O概念: Direct I/O is a way to avoid entire caching layer in the kernel and send the I/O direc ...
- 对象引用 方法传参 值传递 引用传递 易错点 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- 原生JS实现new方法、new一个对象发生的四部、new里面常用的优先级
一.js中new一个对象的过程 首先了解new做了什么,使用new关键字调用函数(new ClassA(…))的具体步骤: 1.创建一个新对象: var obj = {}; 2.设置新对象的const ...
- Python Numpy模块函数np.c_和np.r_
np.r_:是按列连接两个矩阵,就是把两矩阵上下相加,要求列数相等,类似于pandas中的concat(). np.c_:是按行连接两个矩阵,就是把两矩阵左右相加,要求行数相等,类似于pandas中的 ...
- Neo4j 查询某标签节点个数语句 删除某标签全部节点语句
查询:MATCH (n:标签名) RETURN count(n) 删除:MATCH (n:标签名) DELETE n
- OpenNebula学习第一节OpenNebula Front-end Installation
一.说说情怀 随着公司硬件开发资源的不足,构建一个云平台似乎重要了起来.当然,也不是这个平台搭建的主力,出于工作的需求和个人兴趣爱好,接下来就来学习一下OpenNebula相关的东西,这是第一节课,先 ...
- 一个WEB应用的开发流程
转载:http://www.51testing.com/html/56/n-3721856.html 先说项目开发过程中团队人员的分工协作. 一.人员安排 毕业至今的大部分项目都是独立完成,虽然也有和 ...
- Mathematica 文本界面获得之前的结果
使用%号做标记.获得文本界面之前的运算结果: