首页 web前端 js教程 简单谈谈Javascript中类型的判断_javascript技巧

简单谈谈Javascript中类型的判断_javascript技巧

May 16, 2016 pm 03:36 PM
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

<strong>Foo instanceof Foo
</strong>
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,
  /(&#63;:)/,
  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 &#63; 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实现的

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

如何使用WebSocket和JavaScript实现在线语音识别系统 如何使用WebSocket和JavaScript实现在线语音识别系统 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript实现在线语音识别系统引言:随着科技的不断发展,语音识别技术已经成为了人工智能领域的重要组成部分。而基于WebSocket和JavaScript实现的在线语音识别系统,具备了低延迟、实时性和跨平台的特点,成为了一种被广泛应用的解决方案。本文将介绍如何使用WebSocket和JavaScript来实现在线语音识别系

WebSocket与JavaScript:实现实时监控系统的关键技术 WebSocket与JavaScript:实现实时监控系统的关键技术 Dec 17, 2023 pm 05:30 PM

WebSocket与JavaScript:实现实时监控系统的关键技术引言:随着互联网技术的快速发展,实时监控系统在各个领域中得到了广泛的应用。而实现实时监控的关键技术之一就是WebSocket与JavaScript的结合使用。本文将介绍WebSocket与JavaScript在实时监控系统中的应用,并给出代码示例,详细解释其实现原理。一、WebSocket技

如何利用JavaScript和WebSocket实现实时在线点餐系统 如何利用JavaScript和WebSocket实现实时在线点餐系统 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket实现实时在线点餐系统介绍:随着互联网的普及和技术的进步,越来越多的餐厅开始提供在线点餐服务。为了实现实时在线点餐系统,我们可以利用JavaScript和WebSocket技术。WebSocket是一种基于TCP协议的全双工通信协议,可以实现客户端与服务器的实时双向通信。在实时在线点餐系统中,当用户选择菜品并下单

如何使用WebSocket和JavaScript实现在线预约系统 如何使用WebSocket和JavaScript实现在线预约系统 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript实现在线预约系统在当今数字化的时代,越来越多的业务和服务都需要提供在线预约功能。而实现一个高效、实时的在线预约系统是至关重要的。本文将介绍如何使用WebSocket和JavaScript来实现一个在线预约系统,并提供具体的代码示例。一、什么是WebSocketWebSocket是一种在单个TCP连接上进行全双工

JavaScript和WebSocket:打造高效的实时天气预报系统 JavaScript和WebSocket:打造高效的实时天气预报系统 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的实时天气预报系统引言:如今,天气预报的准确性对于日常生活以及决策制定具有重要意义。随着技术的发展,我们可以通过实时获取天气数据来提供更准确可靠的天气预报。在本文中,我们将学习如何使用JavaScript和WebSocket技术,来构建一个高效的实时天气预报系统。本文将通过具体的代码示例来展示实现的过程。We

简易JavaScript教程:获取HTTP状态码的方法 简易JavaScript教程:获取HTTP状态码的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教程:如何获取HTTP状态码,需要具体代码示例前言:在Web开发中,经常会涉及到与服务器进行数据交互的场景。在与服务器进行通信时,我们经常需要获取返回的HTTP状态码来判断操作是否成功,根据不同的状态码来进行相应的处理。本篇文章将教你如何使用JavaScript获取HTTP状态码,并提供一些实用的代码示例。使用XMLHttpRequest

javascript中如何使用insertBefore javascript中如何使用insertBefore Nov 24, 2023 am 11:56 AM

用法:在JavaScript中,insertBefore()方法用于在DOM树中插入一个新的节点。这个方法需要两个参数:要插入的新节点和参考节点(即新节点将要被插入的位置的节点)。

JavaScript和WebSocket:打造高效的实时图像处理系统 JavaScript和WebSocket:打造高效的实时图像处理系统 Dec 17, 2023 am 08:41 AM

JavaScript是一种广泛应用于Web开发的编程语言,而WebSocket则是一种用于实时通信的网络协议。结合二者的强大功能,我们可以打造一个高效的实时图像处理系统。本文将介绍如何利用JavaScript和WebSocket来实现这个系统,并提供具体的代码示例。首先,我们需要明确实时图像处理系统的需求和目标。假设我们有一个摄像头设备,可以采集实时的图像数

See all articles