10betJs之判断数据类型

来源:http://www.chinese-glasses.com 作者:Web前端 人气:177 发布时间:2020-04-15
摘要:时间: 2019-10-04阅读: 126标签: 类型 JavaScript 数据类型判断 JavaScript的数据类型分为两类:原始类型(基本类型)和对象类型(引用类型)。原始类型包括数字、字符串和布尔值,另外有两个特殊

时间: 2019-10-04阅读: 126标签: 类型

JavaScript 数据类型判断

JavaScript 的数据类型分为两类:原始类型(基本类型)和对象类型(引用类型)。原始类型包括数字、字符串和布尔值,另外有两个特殊的原始值:null 和 undefined,除此之外的都是对象。对象还包括两种特殊的对象:数组和函数。

 

下面所有代码表达式如果返回值为 true 表示判断成立,否则不成立,变量 obj 表示需要判断的值。

 

通用方法

 

使用 typeof 运算符

判断数据类型可以使用 typeof 运算符,返回值是一个代表数据类型的字符串(注意是字符串,而且是小写的):

 

typeof 1             // 'number'

typeof 'abc'         // 'string'

typeof false         // 'boolean'

typeof undefined     // 'undefined'

typeof null          // 'object'

typeof {x: 1}        // 'object'

typeof [1, 2, 3]     // 'object'

typeof function() {} // 'function'

typeof 运算符可以有效判断数字、字符串、布尔值和 undefined 等原始类型,不过在面对数组和对象时就无能为力了。

 

借用 Object.prototype.toString() 方法

借用 Object.prototype.toString() 方法可以得到一个表示对象的类型的字符串:

 

var toString = Object.prototype.toString;

toString.call('abc')    // '[object String]'

toString.call(true)     // '[object Boolean]'

toString.call([])       // '[object Array]'

toString.call({})       // '[object Object]'

toString.call(/./)      // '[object RegExp]'

toString.call(new Date) // '[object Date]'

toString.call(Math)     // '[object Math]'

使用该方法可以有效判断数组、函数、日期、正则表达式等对象类型(引用类型)。在 ECMAScript 5 中还可以用这个方法来判断 null

和 undefined:

 

toString.call(null)      // '[object Null]'

toString.call(undefined) // '[object Undefined]'

下面是一些特殊情况。

 

原始类型(基本类型)

 

数字

使用 typeof 运算符可以判断任意数字、NaN 或者 Infinity:

 

typeof NaN      // 'number'

typeof Infinity // 'number'

如果要排除 NaN 和 Infinity 可以使用 isFinite() 方法,不过 isFinite() 方法试图将一些非数字类型转换为数字,因此需要双重保险:

 

typeof obj === 'number' && isFinite(obj)

上面的表达式如果返回为 true 则保证了变量 obj 是数字类型的同时不是 NaN 或者 Infinity,毕竟我们不希望这两个特殊数值参与数学运算。ECMAScript 6 增加的 Number.isFinite() 方法有同样效果。

 

整数

判断一个数是整数并且在安全范围内,利用整数取整后还是与自身相等的特点:

 

typeof obj === 'number' && isFinite(obj)

  && obj > -9007199254740992

  && obj < 9007199254740992

  && Math.floor(obj) === obj

NaN

全局的 isNaN() 方法也试图将一些非数字类型隐式转换为数字,如果转换成功,它会认为这个值是一个数字,否则会认为这是一个 NaN:

 

isNaN(NaN)       // true

isNaN(0/0)       // true 0 除以 0 的结果为 NaN

isNaN('1')       // false 字符串 '1' 可以隐式转换为数字 1

isNaN(true)      // false 布尔值 true 可以隐式转换为数字 1

isNaN([])        // false 空数组可以隐式转换为数字 0

isNaN(Infinity)  // false

isNaN('abc')     // true

isNaN(undefined) // true

字符串 'abc' 和 undefined 都不能隐式转换为一个数字,所以被判断为是一个 NaN。

 

NaN 是一个特殊数值,它不等于任何值,甚至不等于它自己,因此判断一个值为 NaN 的最好方式是判断它是一个数字类型同时不等于自身:

 

typeof obj === 'number' && obj != +obj

ECMAScript 6 增加的 Number.isNaN() 方法更好地解决了这个问题,只有值为 NaN 的时候才会返回 true:

 

Number.isNaN(NaN)        // true

Number.isNaN(Number.NaN) // true

Number.isNaN(0/0)        // true

Number.isNaN(Infinity)   // false

Number.isNaN('abc')      // false

Number.isNaN(undefined)  // false

可以看出 Number.isNaN() 方法和 isNaN() 方法是不一样的。Number.isNaN() 方法仅用于判断是否是特殊值 NaN。

 

布尔值

布尔值不是 true 就是 false,可以使用 typeof 运算符,也可以像下面这样判断:

 

obj === true || obj === false

Undefined

在 ECMAScript 3 中 undefined 是可读写的,所以直接与 undefined 作比较返回的结果不一定是准确的,像这样 var undefined = 1 在有些实现中是可以改变其值的,此时再与之做比较得到的结果就有点出人意料了,通常情况下还是使用 typeof 运算符来判断:

 

typeof obj === 'undefined'

不过使用 typeof 运算符有一个不好的地方是不能区分未定义的变量和值为 undefined 的变量(两者还是有区别的),另外一种方式是使用 void 运算符,因为它的运算结果总是返回 undefined:

 

obj === void 0

Null

使用 typeof 运算符判断 null 将会返回 'object',这明显不是想要的,所以最好的方式是直接与 null 值进行比较:

 

obj === null

这里必须使用 ===,因为 undefined == null 也会返回 true。

 

存在判断

对值为 null 或 undefined 的变量读取属性时会引发错误,因此有时候需要做存在判断,简单地使用 if 语句来判断,会将那些可以隐式转换为 false 的值也一概排除掉了,比如数字0、空字符串、空数组之类的,它们都可以隐式转换为 false,因为 undefined == null 会返回 true,而和其它任何非 null 或者 undefined 的值比较都会返回 false,所以更好的办法是直接与 null 值做比较:

 

if (obj != null) {

  obj.property;

}

这样就可以判断变量 obj 既不是 undefined 也不是 null,或者像下面这样判断:

 

typeof obj !== 'undefined' && obj !== null

通过存在判断才可以放心使用 . 语法获取属性。

 

对象类型(引用类型)

 

对象

要区别 null 和其它对象可以像下面这样判断,因为 null 值可以隐式转换为 false:

 

obj && typeof obj === 'object'

这样判断就可以把 null 给排除掉,变量 obj 是对象或者数组或者其它对象(不包括函数)。下面是另外一种方法:

 

obj === Object(obj)

使用 Object() 方法如果传入的参数不是对象将会被转换为对象,否则,只是简单地将传入的参数返回。该方法可以判断所有对象,包括函数。

 

数组

判断数组的方法:

 

Object.prototype.toString.call(obj) === '[object Array]'

ECMAScript 5 增加了数组检测的原生方法:

 

Array.isArray(obj)

函数

虽然 typeof 运算符将函数特别对待了,但是使用 typeof 运算符在有些实现中不是函数的也会返回 'function',因此还是使用如下方法来判断函数:

 

Object.prototype.toString.call(obj) === '[object Function]'

正则表达式

使用 typeof 运算符判断正则表达式,一般都会返回 'object',不过也有一些实现会返回 'function',所以,还是借用 Object.prototype.toString 方法来判断:

 

Object.prototype.toString.call(obj) === '[object RegExp]'

http://www.bkjia.com/Javascript/923171.htmlwww.bkjia.comtruehttp://www.bkjia.com/Javascript/923171.htmlTechArticleJavaScript 数据类型判断 JavaScript 的数据类型分为两类:原始类型(基本类型)和对象类型(引用类型)。原始类型包括数字、字符串和布尔值,另...

Javascript 中的数据类型判断其实是一个JavaScript非常基础问题,但不论是日常实际编程过程中和还是面试时,这都是一个非常常见的问题。

很多人被问到如何判断一个变量数据类型这个问题时,大概都能回答上几种方法,但是一深入的问题各种判断方法的区别、优劣、局限、原理,却一时半会理不清楚了,所以就借这一篇文章,复习一下JavaScript中这个基础但很容易出错的问题。

typeof

我们都使用 typeof 是用来判断数据类型的命令, 在常规的场景中足以应付数据类型判断的需求:

var obj = { name: 'zhangxiang'};function foo() { console.log('this is a function');}var arr = [1,2,3];console.log(typeof 1); // numberconsole.log(typeof '1'); //stringconsole.log(typeof true); //booleanconsole.log(typeof null); //objectconsole.log(typeof undefined); //undefinedconsole.log(typeof obj); //objectconsole.log(typeof foo); //functionconsole.log(typeof arr); //object

由结果可知typeof可以测试出numberstringbooleanundefinedfunction,而对于null数组对象,typeof均检测出为object,不能进一步判断它们的类型。

所以一般来说, typeof 会使用在比较简单的场景, 比如你几乎可以确定数据是哪一类数据然后稍微加以区分的时候.

顺便吐槽一句,typeof null === 'object' 是JavaScript的一个bug,那么多个版本还一直不肯改过来,什么鬼...

instanceof

instanceof 其实适合用于判断自定义的类实例对象, 而不是用来判断原生的数据类型, 举个例子:

// a.htmlscript var a = [1,2,3];/script

// main.htmliframe src="a.html"/iframescript var frame = window.frames[0]; var a = frame.a; console.log(a instanceof Array); // false console.log(a.contructor === Array); //false console.log(a instanceof frame.Array); // true/script

是什么原因导致上面的结果呢? 其实 iframe 之间不会共享原型链, 因为他们有独立的执行环境, 所以 frame a 中的数组 a 不会是本执行环境的实例对象. 通过特性嗅探同样不靠谱, 像通过 contructor

Sort, slice 等等的特有的数组(或者其他数据类型)方法或属性, 万一对象中也有 sort, slice 属性, 就会发生误判. 所以最靠谱的方法是使用 Object.prototype.toString 方法.

Object.prototype.toString

在任何值上调用 Object 原生的 toString() 方法,都会返回一个 [object NativeConstructorName] 格式的字符串。需要注意的是,但是它不能检测非原生构造函数的构造函数名。

function foo(){};Object.prototype.toString.call(1); '[object Number]'Object.prototype.toString.call('1'); '[object String]'Object.prototype.toString.call(NaN); '[object Number]'Object.prototype.toString.call(foo); '[object Function]'Object.prototype.toString.call([1,2,3]); '[object Array]'Object.prototype.toString.call(undefined); '[object Undefined]'Object.prototype.toString.call(null); '[object Null]'Object.prototype.toString.call(true); '[object Boolean]'

每个类在内部都有一个 [[Class]] 属性,这个属性中就指定了上述字符串中的构造函数名。

Object.prototype.toString 的原理是当调用的时候, 就取值内部的 [[Class]] 属性值, 然后拼接成 '[object ' + [[Class]] + ']' 这样的字符串并返回. 然后我们使用 call 方法来获取任何值的数据类型.

constructor

console.log(bool.constructor === Boolean);// trueconsole.log(num.constructor === Number);// trueconsole.log(str.constructor === String);// trueconsole.log(arr.constructor === Array);// trueconsole.log(obj.constructor === Object);// trueconsole.log(fun.constructor === Function);// trueconsole.log(haoxl.constructor === Student);// falseconsole.log(haoxl.constructor === Person);// true

undefined和null没有contructor属性

constructor不能判断undefined和null,并且使用它是不安全的,因为contructor的指向是可以改变的

有用的数据类型判断函数

本文由10bet发布于Web前端,转载请注明出处:10betJs之判断数据类型

关键词:

最火资讯