首页 > 语言 > JavaScript > 正文

简单谈谈Javascript中类型的判断

2024-05-06 16:24:41
字体:
来源:转载
供稿:网友

这篇文章主要是对判断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"

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

 

 
  1. // 以下代码在版本 Google Chrome 45.0.2454.101 m 中测试通过 
  2. // Numbers 
  3. console.log(typeof 37 === 'number'); 
  4. console.log(typeof 3.14 === 'number'); 
  5. console.log(typeof Math.LN2 === 'number'); 
  6. console.log(typeof Infinity === 'number'); 
  7. console.log(typeof NaN === 'number'); // 尽管NaN是"Not-A-Number"的缩写,意思是"不是一个数字" 
  8. console.log(typeof Number(1) === 'number'); // 不要这样使用! 
  9.  
  10. // Strings 
  11. console.log(typeof "" === 'string'); 
  12. console.log(typeof "bla" === 'string'); 
  13. console.log(typeof (typeof 1) === 'string'); // console.log(typeof返回的肯定是一个字符串 
  14. console.log(typeof String("abc") === 'string'); // 不要这样使用! 
  15.  
  16. // Booleans 
  17. console.log(typeof true === 'boolean'); 
  18. console.log(typeof false === 'boolean'); 
  19. console.log(typeof Boolean(true) === 'boolean'); // 不要这样使用! 
  20.  
  21. // Symbols 
  22. console.log(typeof Symbol() === 'symbol'); 
  23. console.log(typeof Symbol('foo') === 'symbol'); 
  24. console.log(typeof Symbol.iterator === 'symbol'); 
  25.  
  26. // Undefined 
  27. console.log(typeof undefined === 'undefined'); 
  28. console.log(typeof blabla === 'undefined'); // 一个未定义的变量,或者一个定义了却未赋初值的变量 
  29.  
  30. // Objects 使用Array.isArray或者Object.prototype.toString.call方法可以从基本的对象中区分出数组类型 
  31. console.log(typeof {a:1} === 'object'); 
  32. console.log(typeof [1, 2, 4] === 'object'); 
  33. console.log(typeof /^[a-zA-Z]{5,20}$/ === 'object'); 
  34. console.log(typeof {name:'wenzi', age:25} === 'object'); 
  35. console.log(typeof null === 'object');//true 
  36.  
  37. // 下面的容易令人迷惑,不要这样使用! 
  38. console.log(typeof new Boolean(true) === 'object'); 
  39. console.log(typeof new Number(1) === 'object'); 
  40. console.log(typeof new Date() === 'object'); 
  41. console.log(typeof new String("abc") === 'object'); 
  42. console.log(typeof new Error() === 'object'); 
  43.  
  44. // 函数 
  45. console.log(typeof function(){} === 'function'); 
  46. console.log(typeof Math.sin === 'function'); 

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

二、instanceof

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

1、instanceof 和 constructor 没有关系

 

 
  1. var A = function() {}; 
  2. A.prototype = {}; 
  3.  
  4. var B = {}; 
  5. console.log(A.constructor);//function Function() { [native code] } 
  6. console.log(B.constructor);//function Object() { [native code] } 
  7.  
  8. var a = new A(); 
  9. A.prototype = {}; 
  10.  
  11. var b = new A(); 
  12. b.constructor = A.constructor; 
  13.  
  14. console.log(a.constructor === A);//false 
  15. console.log(a.constructor);//function Object() { [native code] } 
  16. console.log(typeof A);//function Object() { [native code] } 
  17.  
  18. console.log(a.constructor === b.constructor);//false 
  19. console.log(b.constructor);//function Function() { [native code] } 
  20.  
  21. console.log(a instanceof A);//false 
  22. console.log(b instanceof A);//true 

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

 

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

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

 

 
  1. //表达式一的指向 
  2. console.log(str.__proto__ === String.prototype);//true 
  3. console.log(str instanceof String); //true 
  4.  
  5. //表达式二的指向 
  6. console.log(String .__proto__ === Function.prototype);//true 
  7. console.log(String instanceof Function);//true 
  8.  
  9. //表达式三的指向 
  10. console.log(str .__proto__ === String.prototype);//true 
  11. console.log(str .__proto__.__proto__ === String.prototype.__proto__);//true 
  12. console.log(str .__proto__.__proto__ === Object.prototype);//true 
  13. console.log(str .__proto__.__proto__.__proto__ === null);//true 
  14. console.log(str instanceof Object);//true 
  15. console.log(str instanceof Function);//false 

再看一个复杂的用法

 

 
  1. console.log(Object instanceof Object);//true 
  2. console.log(Function instanceof Function);//true 
  3. console.log(Number instanceof Number);//false 
  4. console.log(String instanceof String);//false 
  5.  
  6. console.log(Function instanceof Object);//true 
  7.  
  8. console.log(Foo instanceof Function);//true 
  9. console.log(Foo instanceof Foo);//false 

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

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

2、JavaScript 原型继承机制

Object instanceof Object

 

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

 

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

Function instanceof Function

 

 
  1. FunctionL = Function, FunctionR = Function; 
  2. console.log(FunctionL instanceof FunctionR);//true 
  3. console.log(FunctionL.__proto__ === Function.prototype); //true 
  4.  
  5. <strong>Foo instanceof Foo 
  6. </strong> 
  7. function Foo(){} 
  8. var foo = new Foo(); 
  9. FooL = Foo, FooR = Foo; 
  10. console.log(FooL instanceof FooR);//false 
  11. console.log(FooL.__proto__ === Function.prototype );//true 
  12. console.log(FooL.__proto__.__proto__ === Object.prototype );//true 
  13. console.log(FooL.__proto__.__proto__.__proto__ === null );//true 

instanceof 在 Dojo 继承机制中的应用

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

 

 
  1. dojo.declare("Aoo",null,{}); 
  2. dojo.declare("Boo",null,{}); 
  3. dojo.declare("Foo",[Aoo,Boo],{}); 
  4.  
  5. var foo = new Foo(); 
  6. console.log(foo instanceof Aoo);//true 
  7. console.log(foo instanceof Boo);//false 
  8.  
  9. console.log(foo.isInstanceOf(Aoo));//true 
  10. 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是否是数组。

 

 
  1. // 以下代码在版本 Google Chrome 45.0.2454.101 m 中测试通过 
  2. // Numbers 
  3. console.log(37 instanceof Number);//false 
  4. console.log( 3.14 instanceof Number);.//false 
  5. console.log( Math.LN2 instanceof Number);//false 
  6. console.log( Infinity instanceof Number);//false 
  7. console.log( NaN instanceof Number); // false尽管NaN是"Not-A-Number"的缩写,意思是"不是一个数字" 
  8. console.log( Number(1) instanceof Number); // false不要这样使用! 
  9.  
  10. // Strings 
  11. console.log( "" instanceof String);// false 
  12. console.log( "bla" instanceof String);// false 
  13. console.log( ( 1) instanceof String); // falseconsole.log(返回的肯定是一个字符串 
  14. console.log( String("abc"instanceof String); // false 不要这样使用! 
  15.  
  16. // Booleans 
  17. console.log( true instanceof Boolean);// false 
  18. console.log( false instanceof Boolean);// false 
  19. console.log( Boolean(trueinstanceof Boolean); //false 不要这样使用! 
  20.  
  21. // Symbols 
  22. console.log( Symbol() instanceof Symbol);// false 
  23. console.log( Symbol("foo"instanceof Symbol);// false 
  24. console.log( Symbol.iterator instanceof Symbol);// false 
  25.  
  26. // Undefined 
  27. var blabla; 
  28. //console.log( undefined instanceof Undefined);// Uncaught ReferenceError: Undefined is not defined 
  29. //console.log( blabla instanceof Undefined); // Uncaught ReferenceError: Undefined is not defined 
  30. console.log( undefined instanceof Object);// false 
  31. console.log( blabla instanceof Object);// false 
  32.  
  33. // Objects 使用Array.isArray或者Object.prototype.toString.call方法可以从基本的对象中区分出数组类型 
  34. console.log( {a:1} instanceof Object);//true 
  35. console.log( [1, 2, 4] instanceof Object);//true 
  36. console.log( /^[a-zA-Z]{5,20}$/ instanceof Object);//true 
  37. console.log( {name:'wenzi', age:25} instanceof Object);//true 
  38. console.log( null === Object);//false 
  39.  
  40. // 下面的容易令人迷惑,不要这样使用! 
  41. console.log( new Boolean(trueinstanceof Object);//true 
  42. console.log( new Number(1) instanceof Object);//true 
  43. console.log( new Date() instanceof Object);//true 
  44. console.log( new String("abc"instanceof Object);//true 
  45. console.log( new Error() instanceof Object);//true 
  46.  
  47. // 函数 
  48. console.log( function(){} instanceof Function );//true 
  49. 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属性的

 

 
  1. function Person(){ 
  2.  
  3. var Tom = new Person(); 
  4.  
  5. console.log(Tom.constructor === Person);//true 

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

 

 
  1. function Person(){ 
  2.  
  3. function Student(){ 
  4.  
  5. Student.prototype = new Person(); 
  6. var John = new Student(); 
  7. console.log(John.constructor==Student); // false 
  8. console.log(John.constructor==Person); // true 

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

 

 
  1. function Type() { }; 
  2.  
  3. var types = [ 
  4. new Array, 
  5. [], 
  6. new Boolean, 
  7. true// remains unchanged 
  8. new Date, 
  9. new Error, 
  10. new Function, 
  11. function(){}, 
  12. Math,  
  13. new Number, 
  14. 1, // remains unchanged 
  15. new Object, 
  16. {}, 
  17. new RegExp, 
  18. /(?:)/, 
  19. new String, 
  20. "test" // remains unchanged 
  21. ]; 
  22.  
  23. for(var i = 0; i < types.length; i++) { 
  24. types[i].constructor = Type; 
  25. types[i] = [ types[i].constructor, types[i] instanceof Type, types[i].toString() ]; 
  26. }; 
  27.  
  28. console.log( types.join("/n") ); 

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

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

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

 

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

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

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

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

 

 
  1. var m = Object.prototype.toString //501行 
  2.  
  3. E = {};//512行 
  4.  
  5. isFunction: function(a) { //645行 
  6. return p.type(a) === "function" 
  7. }, 
  8. isArray: Array.isArray || function(a) { 
  9. return p.type(a) === "array" 
  10. isWindow: function(a) { 
  11. return a != null && a == a.window 
  12. }, 
  13. isNumeric: function(a) { 
  14. return !isNaN(parseFloat(a)) && isFinite(a) 
  15. }, 
  16. type: function(a) { 
  17. return a == null ? String(a) : E[m.call(a)] || "object" 
  18. }, 
  19. isPlainObject: function(a) { 
  20. if (!a || p.type(a) !== "object" || a.nodeType || p.isWindow(a)) 
  21. return !1; 
  22. try { 
  23. if (a.constructor && !n.call(a, "constructor") && !n.call(a.constructor.prototype, "isPrototypeOf")) 
  24. return !1 
  25. catch (c) { 
  26. return !1 
  27. var d; 
  28. for (d in a) 
  29. return d === b || n.call(a, d) 
  30. }, 
  31. isEmptyObject: function(a) { 
  32. var b; 
  33. for (b in a) 
  34. return !1; 
  35. return !0 
  36. }, 

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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选