Javascript判断数据类型的五种方式及其特殊性
Javascript判断数据类型的五种方式及区别
@
-------------人工分割线-------------
typeof
MDN:typeof操作符返回一个字符串,表示未经计算的操作数的类型。
let data = {
number : 1,
string : 'b',
boolean : true,
symbol : Symbol(),
null : null,
undefined : undefined,
nan : NaN,
function : function (){},
object : {},
array: [],
};
for(let key in data) {
console.log(key + ':::', typeof data[key]);
}
// ----------- 打印结果 ------------------
number::: number
string::: string
boolean::: boolean
symbol::: symbol
null::: object // 需要注意
undefined::: undefined
nan::: number // 需要注意
function::: function
object::: object
array::: object // 需要注意
null、array:打印结果都是object
NaN:打印结果是number
关于null打印成object的原因:属于JS遗留bug,在一开是的JS版本种使用32位系统,为了提高性能使用低位存储变量的类型信息,所以将000 开头代表是对象,但是 null 表示为全零,所在在判断null时也会将它错误的判断为 object 。
instanceof
MDN:instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上
function Animal(name) {
this.name = name;
}
let cat = new Animal('cat');
let dog = new Animal('dog');
console.log(cat instanceof Animal);
console.log(cat instanceof dog); // 报错:Right-hand side of 'instanceof' is not callable
instanceof的右边要求是一个构造函数,否则报错。
如何理解:instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上??:
::: 如:cat instanceof Animal:Animal.prototype是否在cat的原型链上【Animal--Object】,显然是在的,所以返回true。
思考:
function Animal(name) {
this.name = name;
}
let cat = new Animal('cat'); //
// 此时将Animal.prototype指向空对象
let A = {};
Animal.prototype = A;
let cat2 = new Animal('cat2');
console.log(cat instanceof Animal);
console.log(cat2 instanceof Animal);
此时应该打印什么?
先分析cat的原型链:【Animal -- Object】
cat2的原型链:【A --- Object】
此时Animal.prototype指向A对象,所以A在cat2的原型链上,而不在cat上。
所以打印结果:
false
true
总结:先找到Animal.prototype,在列出cat的原型链,如果在就true否则false。
特殊点:
1:instanceof 和多全局对象(例如:多个 frame 或多个 window 之间的交互)
不同的全局环境拥有不同的全局对象,从而拥有不同的内置类型构造函数。这可能会引发一些问题。比如,表达式 [] instanceof window.frames[0].Array 会返回 false,因为 Array.prototype !== window.frames[0].Array.prototype,并且数组从前者继承。
2: String 对象和 Date 对象都属于 Object 类型和一些特殊情况
let simpleStr = 'simpleStr';
let myObj = {};
let myNullObj = Object.create(null);
console.log(simpleStr instanceof String); //false [检查原型链会找到 undefined]
console.log(myObj instanceof Object); //true
console.log(myNullObj instanceof Object); //false [一种创建非 Object 实例的对象的方法]
Object.prototype.toString
MDN:方法返回一个表示该对象的字符串。
// 数据源看开头的代码
for(let key in data) {
console.log(key + ':::', Object.prototype.toString.call(data[key]));
}
/*
number::: [object Number]
string::: [object String]
boolean::: [object Boolean]
symbol::: [object Symbol]
null::: [object Null]
undefined::: [object Undefined]
nan::: [object Number] // 需要注意
function::: [object Function]
object::: [object Object]
array::: [object Array]
* */
为了每个对象都能通过 Object.prototype.toString() 来检测,需要以 Function.prototype.call() 或者 Function.prototype.apply() 的形式来调用,传递要检查的对象作为第一个参数,称为 thisArg。
Object.prototype.toString 的原理是当调用的时候, 就取值内部的 [[Class]] 属性值, 然后拼接成 '[object ' + [[Class]] + ']' 这样的字符串并返回. 然后我们使用 call 方法来获取任何值的数据类型.
isArray
MDN:如果对象是 Array ,则返回true,否则为false。
这个比较简单不写例子了。
特殊性:当检测Array实例时, Array.isArray 优于 instanceof,因为Array.isArray能检测iframes.
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray(1,2,3); // [1,2,3]
// Correctly checking for Array
Array.isArray(arr); // true
// Considered harmful, because doesn't work though iframes
arr instanceof Array; // fals
iisNaN
MDN:用来确定一个值是否为NaN 。注:isNaN函数内包含一些非常有趣的规则;你也可以使用 ECMAScript 2015 中定义的 Number.isNaN() 来判断。与 JavaScript 中其他的值不同,NaN不能通过相等操作符(== 和 ===)来判断 ,因为 NaN == NaN 和 NaN === NaN 都会返回 false。 因此,isNaN 就很有必要了。
isNaN(NaN); // true
isNaN(undefined); // true
isNaN({}); // true
isNaN(true); // false
isNaN(null); // false
isNaN(37); // false
// strings
isNaN("37"); // false: 可以被转换成数值37
isNaN("37.37"); // false: 可以被转换成数值37.37
isNaN("37,5"); // true
isNaN('123ABC'); // true: parseInt("123ABC")的结果是 123, 但是Number("123ABC")结果是 NaN
isNaN(""); // false: 空字符串被转换成0
isNaN(" "); // false: 包含空格的字符串被转换成0
// dates
isNaN(new Date()); // false
isNaN(new Date().toString()); // true
isNaN("blabla") // true: "blabla"不能转换成数值
// 转换成数值失败, 返回NaN
一个有用的特性:
有许多方式来看待isNaN():如果isNaN(x)返回false,那么x在任何算数表达式中都不会使表达式等于NaN;如果返回true,x会使所有算数表达式返回NaN。这就意味着,在JavaScript中,isNaN(x)==true等价于x-0=NaN(在JavaScript中 x-0 == NaN 总是返回false,所以你不用去测试它)。
实际上, isNaN(x), isNaN(x - 0),isNaN(Number(x)), Number.isNaN(x - 0),和Number.isNaN(Number(x)) 的返回值都是一样的 并且在JavaScript中isNaN(x)是这些表达式中最短的表达。
Javascript判断数据类型的五种方式及其特殊性的更多相关文章
- javascript 判断数据类型的几种方法
javascript 判断数据类型的几种方法一.typeof 直接返回数据类型字段,但是无法判断数组.null.对象 typeof 1 "number" typeof NaN &q ...
- javaScript中定义类或对象的五种方式
第一种方式: 工厂方法 能创建并返回特定类型的对象的工厂函数(factory function). function createCar(sColor){ var oTempCar = new Obj ...
- Android数据存储五种方式总结
本文介绍Android平台进行数据存储的五大方式,分别如下: 1 使用SharedPreferences存储数据 2 文件存储数据 3 SQLite数据库存储数据 4 使用Cont ...
- JavaScript判断数据类型总结
最近做项目中遇到了一些关于javascript数据类型的判断处理,上网找了一下资料,并且亲自验证了各种数据类型的判断网页特效,在此做一个总结吧! 一.JS中的数据类型 1.数值型(Number):包 ...
- javascript创建类的6种方式
javascript创建类的7种方式 一 使用字面量创建 1.1 示例 var obj={}; 1.2 使用场景 比较适用于临时构建一个对象,且不关注该对象的类型,只用于临时封装一次数据,且不适合代码 ...
- JavaScript事件处理程序的3种方式
最近这段时间因为每天要修改网站,为网站做特效,所以看了很多的js接触事件,自己只会使用一小部分,有时用的时候也比较混乱,现在系统的整理了一下,首先跟大家在马海祥博客上跟大家分享的是JavaScript ...
- Spring事务配置的五种方式和spring里面事务的传播属性和事务隔离级别
转: http://blog.csdn.net/it_man/article/details/5074371 Spring事务配置的五种方式 前段时间对Spring的事务配置做了比较深入的研究,在此之 ...
- Java Map集合 遍历 五种方式(包含 Lambda 表达式遍历)
示例代码如下: package com.miracle.luna.lambda; import java.util.HashMap; import java.util.Iterator; import ...
- js中判断数据类型的四种方法总结
js中判断数据类型的四种方法 前言 在js中,我们经常需要判断数据的类型,那么哪些方法可以用来判断数据的类型呢?哪种方法判断数据类型最准确呢? 我们来一个个分析: 1.typeof typeof是一个 ...
随机推荐
- leetcode刷题-47全排列2
题目 给定一个可包含重复数字的序列,返回所有不重复的全排列. 思路 其思路与46题完全一致,但是需要与组合总和2题一般,在同一层取出重复元素.因此可以在每一层设置一个set()类型,将访问过的元素放入 ...
- get_started_3dsctf_2016
题外:这道题不是很难,但是却难住了我很久.主要是在IDA中查看反编译出的伪代码时双击了一下gets()函数,结果进入gets函数内部,我当时就懵了,误以为这是一个自定义函数,但是自定义函数应该应该不能 ...
- [LeetCode]64. 最小路径和(DP)
题目 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4 ...
- SpringCloud实战 | 第二篇:SpringCloud整合Nacos实现注册中心
前言 随着eureka的停止更新,如果同时实现注册中心和配置中心需要SpringCloud Eureka和SpringCloud Config两个组件;配置修改刷新时需要SpringCloud Bus ...
- Linq To EF 用泛型时生成的Sql会查询全表的问题
1.问题的现象 public class LinqHepler<T> where T:class { private EFDBContext _context = null; /// &l ...
- matlab中矩阵的表示与简单操作
原文地址为:matlab矩阵的表示和简单操作 一.矩阵的表示在MATLAB中创建矩阵有以下规则: a.矩阵元素必须在”[ ]”内: b.矩阵的同行元素之间用空格(或”,”)隔开: c.矩阵的行与行之间 ...
- MySql基础_DDL_DML_DQL(资料一)
今日内容 数据库的基本概念 MySQL数据库软件 安装 卸载 配置 SQL 数据库的基本概念 1. 数据库的英文单词: DataBase 简称 : DB 2. 什么数据库? * 用于存储和管理数据的仓 ...
- xss利用——BeEF#stage2(初始并持续化控制)
全文概览 浏览器攻击方法流程 攻击浏览器一般分为几个阶段,如下图 整个过程分为三个步骤,第一步是初始化控制,第二步是持续控制,第三步是攻击.在第三步中的七个攻击方法是可以交叉的,比如可以同时攻击用户和 ...
- linux与linux间,互相拷贝文件
直接使用scp命令 和远程Linux主机 进行文件的拷贝 1.可以将远程Linux系统上的文件拷贝到本地计算机 2.也可以将本地计算机上的文件拷贝到远程Linux系统上. 比如:我们要拷贝 ...
- Python-维护排序好的序列模块-bisect
bisect模块 处理已经排序的序列,升序,从小到大,分插入数据和查看插入数据的位置两大核心,类似于插入排序算法 插入数据 # 首先这个序列按升序规则已经排序好的 # 查找规则是二分查找,当数据相等的 ...