类型和原生函数及类型转换(二:终结js类型判断)
- typeof
- instanceof
- isArray()
- Object.prototype.toString.call()
- DOM对象与DOM集合对象的类型判断
一、typeof
typeof是一个一元运算符,放在任意类型的运算数前,这个运算返回的是字符串,该字符串说明的是运算数的类型。
在原始值类型中除了null都能正确的返回对应的类型字符串名称,即:number、string、boolean、undefined可以正确判断类型。typeof null ==> object。
但是需要注意的typeof NaN 是 number,除了正常的数值以外,还有Number.MAX_VALUE、Number.MIN_VALUE、Number.NaN、Number.POSITIVE_INFINITY、Number.NEGATIVE_INFINITY都是返回number。(NaN在类型上本身就属于数字的一种,其他特别的数值那也肯定是数值)
在引用值类型中Function返回的是function,但是Array却又返回的是object。
其余的引用值类型都是返回object。
注意:typeof(obj)判断的obj如果未定的话也不会报错,而是返回“undefined”。
---------------------------------------------------------------------------------------------------
懒人理解区:
(简析:number,string,boolean,object,undefined,object,function可以正确的获取对应的类型字符串值,typeof遇到数组,对象,null都是返回object。)
二、instanceof
instanceof的内部机制是通过判断对象的原型链中是否能不能找到类型的prototype(原型)。在原型链上能找到对应的原型就会返回true。
1 instanceof Number // false
new Number(1) instanceof Number// true
{} instanceof Object // 会报错,这是语法错误,这里的{}并不表示对象
var a = {}
a instanceof Object // true
null instanceof Object // false
[] instanceof Array // true
那是不是就就可以用instanceof配合typeof来完成数组的判断呢?别急看一下代码:
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray(1,2,3,4,5);
//这个写法IE下不支持,标准浏览器firefox,chrome下可以实现
console.log(arr);//打印出:[1,2,3,4,5]
console.log(arr instanceof Array);//false
console.log(arr.constructor === Array);//false
跨框架iframe的时候使用页面中的数组时,会失败,因为在不同的框架iframe中,创建的数组是不会相互共享其prototype属性的。类似将外层Array原型直接克隆到自己的内部window上,而instanceof的内部是基于原型链来判断,所以就没法判断了。
三、isArray()
用来判断对象是否是数组,是ES5标准的方法,在低版本的浏览器上不兼容。
Array.isArray(obj)
这个方法用来做类型判断的意义不大,除非做一些纯粹的移动端web开发或者确定只兼容ES5标准的浏览器项目。
四、Object.prototype.toString.call()
这个方法的使用我在上一篇博客:类型和原生函数及类型转换(一)末尾做了详细介绍,就不在这里赘述了,不是很了解的话可以到上一篇博客详细了解,这篇博客我主要就实现原理剖析。
在ES5.1中,除了规范写的更详细一些以外,Object.prototype.toString方法和[[class]]内部属性的定义上也有一些变化,Object.prototype.toString方法的规范如下:
15.2.4.2 Object.prototype.toString ( )
在toString方法被调用时,会执行下面的操作步骤:
- 如果this的值为undefined,则返回
"[object Undefined]"
.- 如果this的值为null,则返回
"[object Null]"
.- 让O成为调用ToObject(this)的结果.
- 让class成为O的内部属性[[Class]]的值.
- 返回三个字符串"[object ", class, 以及 "]"连接后的新字符串
.
如果你对JavaScript的值类型有所了解就知道,undefined和null没有包装类(在我上一篇博客中有介绍),如果要将这两个值类型的变量作为对象来使用在代码中会报错(这里涉及到了隐式类型转换),在ES3中这两个值类型的变量就没办法使用Object.prototype.toString.call()这种方式来实现类型判断(ES3中没有对这两个值类型的变量做特殊处理)。
所有内置对象的[[Class]]属性的值是由本规范定义的.所有宿主对象的[[Class]]属性的值可以是除了"Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", "String"之外的的任何字符串.[[Class]]内部属性是引擎内部用来判断一个对象属于哪种类型的值的.需要注意的是,除了通过Object.prototype.toString方法之外,本规范没有提供任何其他方式来让程序访问该属性的值(查看 15.2.4.2)
最后来一个兼容的ES5的类型判断方法,ES6中的Object.prototype.toString.call()有些改变,是因为[[class]]内部属性没有,取而代之的是另外一个内部属性[[NativeBrand]].[[NativeBrand]]属性,但是toString方法的实现逻辑依然没有差别,后期在ES6部分我再将对应的兼容方法写出来。
function myTypeof(value){
var result = NaN;
var valOf = typeof value;
var inOf = value instanceof String || value instanceof Number || value instanceof Boolean;
var typeObj = {
"[object Object]":"object",
"[object Array]":"array",
"[object Function]":"function",
"[object Date]":"date",
"[object Error]":"error",
"[object JSON]":"json",
"[object Math]":"math",
"[object RegExp]":"regExp",
"[object Boolean]":"boolean",
"[object String]":"string",
"[object Number]":"number",
"[object Undefined]":"undefined",
"[object Null]":"null"
} var str = Object.prototype.toString.call(value);
for(var i in typeObj){
if(i == str){
result = typeObj[i];
break;
}
}
if( result === "number" && isNaN(value)){ //此处可以考虑 value === "NaN"这种情况
return NaN;
}
if( inOf && valOf === "object"){
return result + "-Object";
}
return result;
}
五、DOM对象与DOM集合对象的类型判断
<div class="demo"></div>
//js
var do = document.getElementsByClassName("demo");
Object.prototype.toString.call(do);//"[object HTMLCollection]"
Object.prototype.toString.call(document);//"[object HTMLDocument]"
类型和原生函数及类型转换(二:终结js类型判断)的更多相关文章
- 类型和原生函数及类型转换(三:终结js类型转换)
Number() parseInt() parseFloat() Boolean() String() toString() 一.显式类型转换 -------Number()函数把对象的值转换为数字. ...
- 自己写一个swap函数交换任意两个相同类型元素的值 对空指针的使用 字节大小的判断(二)了解原理
验证的代码: #include <stdio.h> int main(){ char c = 'z'; ) + (c << ) + () + 'a'; printf(" ...
- Scala 基础(十二):Scala 函数式编程(四)高级(二)参数(类型)推断、闭包(closure)、函数柯里化(curry)、控制抽象
1 参数(类型)推断 参数推断省去类型信息(在某些情况下[需要有应用场景],参数类型是可以推断出来的,如list=(1,2,3) list.map() map中函数参数类型是可以推断的),同时也可以 ...
- 《你不知道的JavaScript》整理(五)——值与原生函数
一.值 1)数字 JavaScript只有一种数值类型:number(数字),包括"整数"和带小数的十进制数. //数字的语法 a.toExponential(); // &quo ...
- 《You dont know JS》原生函数
原生函数 原生函数,即JavaScript的内建函数(built-in function).常用的原生函数有String().Number().Boolean().Array().Object().F ...
- PHP 常用函数总结(二)
4.PHP处理数据库的常用函数. 汇总表 PHP 5 MySQLi 函数 函数 描述 mysqli_affected_rows() 返回前一个 Mysql 操作的受影响行数. mysqli_autoc ...
- 理解函数式编程中的函数组合--Monoids(二)
使用函数式语言来建立领域模型--类型组合 理解函数式编程语言中的组合--前言(一) 理解函数式编程中的函数组合--Monoids(二) 继上篇文章引出<范畴论>之后,我准备通过几篇文章,来 ...
- 学习Python函数笔记之二
---恢复内容开始--- 1.内置函数:取绝对值函数abs() 2.内置函数:取最大值max(),取最小值min() 3.内置函数:len()是获取序列的长度 4.内置函数:divmod(x,y),返 ...
- 从函数式编程到Ramda函数库(二)
Ramda 基本的数据结构都是原生 JavaScript 对象,我们常用的集合是 JavaScript 的数组.Ramda 还保留了许多其他原生 JavaScript 特性,例如,函数是具有属性的对象 ...
随机推荐
- LeetCode算法题-Set Mismatch(Java实现)
这是悦乐书的第279次更新,第295篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第147题(顺位题号是645).集合S最初包含从1到n的数字. 但不幸的是,由于数据错误 ...
- Windows操作系统分类
Windows主要有桌面版和服务器版.移动版三个版本 桌面版现在主流是WindowsXP.WindowsVista.Windows7.Windows8.Windows10 其中WindowsXP已经被 ...
- vue 路由变化页面数据不刷新问题(缓存)
每天记录一点点,把我遇到的问题记录下来, 希望可以帮助到更多和我遇到同样问题的人. 问题描述:通过调接口,动态显示帮助页面的问题列表, 问题列表有多级,当点击的这个问题没有下一级问题的时候跳入内容页. ...
- SQL CREATE INDEX 语句
CREATE INDEX 语句用于在表中创建索引. 在不读取整个表的情况下,索引使数据库应用程序可以更快地查找数据. 索引 您可以在表中创建索引,以便更加快速高效地查询数据. 用户无法看到索引,它们只 ...
- centos查看系统信息命令
1.cd - :返回上次所在的目录 2.查看系统版本 cat /etc/redhat-release 3.查看linux内核版本1)cat /proc/version 2) uname -a3) un ...
- SQL分组求每组最大值问题的解决方法收集 (转载)
例如有一个表student,其结构如下: id name sort score 1 张三 语文 82 2 李四 数 ...
- Kaggle教程——大神教你上分
本文记录笔者在观看Coursera上国立经济大学HLE的课程 How to win a data science competetion中的收获,和大家分享.课程的这门课的讲授人是Kaggle的大牛, ...
- Centos查看tomcat状态及操作
启动:一般是执行sh tomcat/bin/startup.sh 查看:执行ps -ef |grep tomcat 输出如下 www 5144 ...等等.Bootstrap start 说明tomc ...
- 【学习总结】GirlsInAI ML-diary day-12-for循环
[学习总结]GirlsInAI ML-diary 总 原博github链接-day12 认识for循环执行 ps: range()函数 python range() 函数可创建一个整数列表,一般用在 ...
- java 反射的基本操作
一.反射的概述JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为j ...