简单谈谈Javascript中类型的判断_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实现的

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索javascript
, 判断类型
Javascript类型判断
javascript nan判断、javascript null判断、javascript 类型判断、javascript 数字判断、javascript 判断数组,以便于您获取更多的相关知识。

时间: 2024-09-29 19:44:49

简单谈谈Javascript中类型的判断_javascript技巧的相关文章

谈谈JavaScript中function多重理解_javascript技巧

JavaScript 中的 function 有多重意义.它可能是一个构造器(constructor),承担起对象模板的作用: 可能是对象的方法(method),负责向对象发送消息.还可能是函数,没错是函数,和对象没有任何关系独立存在的可以被调用的函数. 由于语言设计者的妥协,在 JavaScript 加入了一些 class 相关的特性,以使 JavaScript 看起来确实象 Java,可以 "面向对象".虽然 JavaScript 添加了 new 和 this, 但却没有 clas

简单谈谈JavaScript的同步与异步_javascript技巧

1.手绘一张图说明. 2.为什么JavaScript是单线程(这里引用阮一峰老师的话) JavaScript的单线程,与它的用途有关. 作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM. 这决定了它只能是单线程,否则会带来很复杂的同步问题. 比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准? 所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经成了这门语言的核心

简单谈谈javascript中的变量、作用域和内存问题_javascript技巧

[变量] [1]定义:可变的量,相当于给一个不定的数据起了一个外号.变量是存储信息的容器. [2]特性:js中的变量是松散类型的,可以保存任何类型的数据.它只是在特定时间用于保存特定值的一个名字而已.由于不存在定义某个变量必须要保存何种数据类型值的规则,变量的值及其数据类型可以在脚本的生命周期内改变. [3]变量声明:变量可以在声明时赋值,但不能有其他操作,如+=.-=等 var a = 2;//是正确的 var a += 2;//是错误的 var a = 2++;//是错误的,++只能用于变量

简单谈谈javascript中this的隐式绑定_基础知识

我们先来看一个例子 function foo() { console.log( this.a ); } var obj = { a: 2, foo: foo }; obj.foo(); // 2 this指向了obj,因为foo执行时的call-site(可以理解为调用时所在作用域)在obj上面.注意是运行的时候,和在哪里声明的没有关系. call-site and call-stack call-site姑且理解为调用域,call-stack为调用栈.如下代码可以辅助我们理解 function

详解Javascript中的Object对象_javascript技巧

Object是在javascript中一个被我们经常使用的类型,而且JS中的所有对象都是继承自Object对象的.虽说我们平时只是简单地使用了Object对象来存储数据,并没有使用到太多其他功能,但是Object对象其实包含了很多很有用的属性和方法,尤其是ES5增加的方法,因此,本文将从最基本的介绍开始,详细说明了Object的常用方法和应用. 基础介绍 创建对象 首先我们都知道,对象就是一组相似数据和功能的集合,我们就是用它来模拟我们现实世界中的对象的.那在Javascript中,创建对象的方

Flow之一个新的Javascript静态类型检查器_javascript技巧

今天我们兴奋的发布了 Flow 的尝鲜版,一个新的Javascript静态类型检查器.Flow为Javascript添加了静态类型检查,以提高开发效率和代码质量.更明确的说,静态类型检查提供的好处像早期错误检查,帮助你发现一些只有在运行时才能发现的错误,以及代码智能感知,它会帮助代码维护,查找,重构和优化. 我们设计Flow的所有功能构建在现有Javascript规范之上.因为Flow主动地在后台工作,所以额外的编译开销很小.Flow并不要求开发者如何编写代码 -- 她用一套复杂的算法分析你熟悉

理解JavaScript中Promise的使用_javascript技巧

Javascript 采用回调函数(callback)来处理异步编程.从同步编程到异步回调编程有一个适应的过程,但是如果出现多层回调嵌套,也就是我们常说的厄运的回调金字塔(Pyramid of Doom),绝对是一种糟糕的编程体验.于是便有了 CommonJS 的 Promises/A 规范,用于解决回调金字塔问题.本文先介绍 Promises 相关规范,然后再通过解读一个迷你的 Promises 以加深理解. 什么是 Promise一个 Promise 对象代表一个目前还不可用,但是在未来的某

探索Javascript中this的奥秘_javascript技巧

前言: this 是 JavaScript 比较特殊的关键字,运用的地方之广,方式之灵活奠定了它的强大,但同时注定了它的难用 .自己刚开始学的时候被绕的很晕,为了彻底弄懂它查了很多资料.然后将自己学的东西整理了一下,以通俗易懂的方式表达出来,权当做学习笔记,同时也可以给有需要的童鞋做下参考^_^ 什么是this? this 关键字的含义是明确且具体的,即指代当前对象.即意味着这个 this 是在某种相对情况下才成立的. this 被分为三种情况:全局对象.当前对象或者任意对象;判断处于那种情况,

JavaScript中的prototype使用说明_javascript技巧

1.prototype 在JavaScript中并没有类的概念,但JavaScript中的确可以实现重载,多态,继承.这些实现其实方法都可以用JavaScript中的引用和变量作用域结合prototype来解释. 2.简单的例子 复制代码 代码如下: var Blog = function( name, url ){ this.name = name; this.url = url; }; Blog.prototype.jumpurl = ''; Blog.prototype.jump = fu