走进javascript——类型
ECMAScript语言类型对应于使用ECMAScript语言的ECMAScript程序员直接操作的值。ECMAScript语言类型有以下几种Undefined,Null,Boolean,String,Symbol,Number和Object。ECMAScript语言值是以ECMAScript语言类型为特征的值。
如果你奇怪为什么这里没有写Function类型,并且把Null也当做一种类型,建议你看一下hax在知乎上的一个回答JavaScript 里 Function 也算一种基本类型?
简单说:按照规范,typeof只是一个运算符,其返回值并不能作为JS类型系统的依据。
typeof null == ‘object’ ?
摘录在网上看到的一段话:
我听到很多次人们声称`typeof null =='object''是某种意图,表示'null'应该是一个“空对象引用”值,他们进一步使用当前的“任何对象价值”的措辞来支持这种说法。我相信这是非常不准确的,至少就JS今天而言,正如Brendan Eich自己所说的那样,'typeof null =='object'只是一个错误,而不是一个有意的功能或者如何使用它的信号。
MDN上这样说:
在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是0。由于
null代表的是空指针(大多数平台下值为0x00),因此,null的类型标签也成为了0,typeof null就错误的返回了"object"
关于null == ‘object’的更多信息,你可以去看看The history of “typeof null”这篇文章。译文 typeof null的前世今生
Symbol类型?
恩,它是ES6新增的啦,主要用来解决命名冲突,如果你感兴趣可以看一下下面这篇文章。
用 instanceof 判断对象类型?
用instanceof来判断对象类型多少有些不合适,因为instanceof是用来判断某个对象的原型链是否存在于某个构造函数的prototype上的,因原型链这一层关系导致部分情况下用instanceof来判断对象类型就变得不是那么准确了,比如判断数组的类型。

导致这个原因是因为所有对象都继承至Object.prototype,当然,通过Object.create(null)方式创建对象,原型是不会指向Object.prototype的。
这里推荐一篇关于instanceof的文章JavaScript instanceof 运算符深入剖析
通过constructor属性来判断对象类型是个好方法?
MDN上是这样说的:
返回一个指向创建了该对象原型的函数引用。需要注意的是,该属性的值是那个函数本身,而不是一个包含函数名称的字符串。对于原始值(如1,
true或 "test"),该属性为只读。
将这句话翻译成代码就是这样:
function fn(){}
new fn().constructor //等于fn.prototype.constructor
而这个fn.prototype.constructor就是指向fn本身,因而有些人就想着通过constructor来判断某个对象的类型,如下图

看起来通过constructor来判断对象类型是个不错的方法,更重要的是还能判断自定义对象类型。
虽然说通过constructor来判断对象类型是一个方案,但这种方法并不是总正确的,主要还是因为这个constructor指向的是构造函数prototype.constructor属性,而这个值我们是可以手动更改的,如下面这样:
function fn(){}
fn.prototype = new Object();
new fn().constructor == fn //false
new fn().constructor == Object //true
我们手动将fn.prototype指向一个新对象,它的执行结果如下:
fn.prototype = {}.__proto__.prototype.constructor // Object
如果你实在是想用constructor来判断对象类型,那么在像上面那种情况时,你可以这样去做:
function fn(){}
fn.prototype = new Object();
fn.prototype.constructor = fn;
借用toString方法判断对象类型

我们来看一下规范是怎么定义这个toString方法的
ToString转换
| 输入类型 | 结果 |
|---|---|
| Undefined | "undefined" |
| Null | "null" |
| Boolean | 如果参数是 true,那么结果为 "true"。如果参数是 false,那么结果为 "false"。 |
| Number | 结果等于输入的参数(不转换)。 |
| String | 参见下文的文法和注释。 |
| Object | 应用下列步骤:调用 ToPrimitive( 输入参数 , 暗示 字符串类型)。调用 ToString(Result(1))。返回 Result(2)。 |
话说规范写的有些苦涩哈,我们还是看一下MDN上怎么说的吧
每个对象都有一个 toString() 方法,当对象被表示为文本值时或者当以期望字符串的方式引用对象时,该方法被自动调用。默认情况下,toString() 方法被每个继承自
Object的对象继承。如果此方法在自定义对象中未被覆盖,toString()返回 "[object type]",其中type是对象类型。
也就是说当我们调用Object中的toString方法时,它会返回"[object type]"这么个东西,但问题是像Number、Boolean、String类型的值它们都是有自己的toString方法的,因此我们必须借用Object中的toString方法,也就是用call、apply或bind方法。
undefined和null的那点事
MDN对null的解释是:
null是一个 JavaScript 字面量,表示空值(null or an "empty" value),即没有对象被呈现(no object value is present)。它是 JavaScript 原始值 之一。
再来看看undefined
undefined是全局对象的一个属性。也就是说,它是全局作用域的一个变量。undefined的最初值就是原始数据类型undefined。一个没有被赋值的变量是undefined类型。一个方法或者是语句如果在执行期间没有变量被赋值也会返回undefined,一个函数如果没有
返回值,就会返回一个undefined值。
undefined和null的不同点
null是一个字面量(而不是全局对象的一个属性,
undefined是)。在 APIs 中,null常被放在期望一个对象,但是不引用任何对象的参数位置。当检测 null 或 undefined 时,注意相等()与全等(=)两个操作符的区别 (前者会执行类型转换)。
在使用上还有一个区别就是,我们可以将一个对象赋值为null,从而告诉垃圾回收器这个对象可以回收了,那么为什么不将对象赋值为undefined呢?我觉得undefined本身就是一个值,而null才是真的没有,如果你对此不太理解,可以看一下下面这个链接 w3c上说的“可以通过将变量的值设置为 null 来清空变量”中的清理变量有什么特别意思吗?
在aimingoo的一篇文章中他是这样说的:无废话JavaScript(上)
hax:
大哥你好像漏了null。。。
aimingoo:
null是Object,所以不必单独提出来讲。我记得我曾经问到过你关于null和undefined的问题,你说在邮件列表中对这个问题讨论得很多,但无有答案。其实我后来想明白了,JS中有两套类型体系,各有一个“无”的概值。基本的6种类型中,undefined表示无;对象系统中,null表示无。
例如,DOM是基于对象系统的,所以适宜于用null来填写attribute中的无值;而var声明的无值变量,由于是基于基本类型系统,所以适宜于用undefined。
当然,也可以直接说js内部以及语言级别或引擎级别用undefined,而js外部或扩展用null。这个与上面大概相同,但思考角度有异。
undefined == null ?
主要还是因为隐式转换导致的。
null是一个表示"无"的对象,转为数值时为0;undefined是一个表示"无"的原始值,转为数值时为NaN。
推荐阅读
探索JavaScript中Null和Undefined的深渊
巧用typeof判断一个未定义的变量,不报错
我们知道如果使用一个未定义的变量是会报错的,但是用typeof判断一个未定义的变量是不会报错的,我觉得这也合理,因为typeof只是用来判断,而不是去操作。
---------- 2017-05-07更新 -----------------
javascript的typeof返回哪些数据类型
object number function boolean underfind symbol
为什么要有不同的数据类型?
- 当程序知道它所要处理的数据的类型之后,能够降低存储空间总量,并且能提高访问速度.例如:可以使用4个字节的计算机存储器量来存放数值243787452.如果将相同的数值存储为字符,则会占涌9个存储器量。
- 不同的数据需要的方法也会不同,如果只有一种数据类型那么问题就大了。
当将数据分成不同的类型以后,有时又会有需求,将一种数据类型转换成另外一种数据类型,甚至有时是不需要区分数据类型。
强制类型转换和隐式类型转换
强制类型转换
转数字:parseInt Number parseFloat
转字符串:toFixed toPrecision toExponential toString JSON.stringify join
转布尔:Boolean
转对象:JSOS.parse
转数组:split
数字转数组 String.prototype.split.call(1123,null);
隐式类型转换
转数字:- * / % ~ +var -var Math.ceil Math.floor Math.abs Math系列
转字符串:+
将js中的值赋值给所有和DOM相关的内容,都会自动转换成字符串。
转布尔:! isNaN 所有和判断相关
JS中为什么要有隐式转换
js在ECMAScript3出现之前是没有异常处理的。这就可以解释为什么这门语言为什么如此频繁的自动强制 转换而且出错的时候总是那么沉默,是因为它从一开始就没有抛出异常。
巧用parseInt判断某个数字是否是整数
10.8 == parseInt(10.8) // 如果parseInt后的值和之前的值一样大,那么是整数
走进javascript——类型的更多相关文章
- javascript类型与类型检测
1.javascript类型: 注:包装对象:如"hello".length实际为js为我们隐式创建了一个String临时对象,去调用该对象的length属性,调用过后再将该临时对 ...
- javascript类型注意事项
以下是javascript类型的注意事项: null:表示尚未存在的对象,注意,尽管尚未存在,也是个对象啊,所以用typeof检测一个null值变量的结果是Object:不过,为了便于写if语句,在j ...
- 谈谈JavaScript类型检测
javascript内置的类型检测机制并非完全可靠.比如typeof操作符,并不能准确的判断数据是哪个类型,比如:数组和对象就不能通过typeof来区分. typeof [] ==="o ...
- Javascript类型检测
原地址 http://www.cnblogs.com/fool/archive/2010/10/07/javascrpt.html 开门见山,我们先来看一下代码: var is = function ...
- JavaScript 类型浅解
对于JavaScript 类型,可简单地概括为:相对于强类型语言来说,它是弱(松散)类型的语言:有基本类型和引用类型,他们是区别是一个有固定空间存在于栈内存中,一个没有固定空间保存在堆内存中并且在栈内 ...
- JavaScript类型和语法
JavaScript类型和语法 一.类型 1.内置类型(null.undefined.boolean.number.string.object.symbol(es6中新增))(除对象之外,其它统称为基 ...
- JavaScript权威设计--JavaScript类型,值,变量(简要学习笔记三)
1.负号是一元求反运算 如果直接给数字直接量前面添加负号可以得到他们的负值 2.JavaScript中的运算超出了最大能表示的值不会报错,会显示Infinity. 超出最小也不报错,会显示-I ...
- JavaScript类型判断instanceof与typeof对比
经常有人会在JavaScript里写如下的方法: function checkType() { var s1 = 123; var s2 = "OK"; if (s1 instan ...
- JavaScript –类型之我晕
每次写博我觉得取上恬当的题目比整篇行文都难,词量有限的情况下突然想到JavaScript拾遗应该会是一个非常文艺而夺目的博文题目,但我并没有急着使用,经验告诉我应该先去搜一下看有没有被用过.果不其然, ...
随机推荐
- 深入浅出数据结构C语言版(1)——什么是数据结构及算法
在很多数据结构相关的书籍,尤其是中文书籍中,常常把数据结构与算法"混合"起来讲,导致很多人初学时对于"数据结构"这个词的意思把握不准,从而降低了学习兴趣和学习信 ...
- AQS阻塞唤醒工具LockSupport
LockSupport在JDK源码中描述为:构建锁和其他同步类的基本线程阻塞原语,构建更高级别的同步工具集.LockSupport提供的park/unpark从线程的粒度上进行阻塞和唤醒,park/u ...
- java开发中获取路径的一些方式
1.servlet开发获取WebContent(项目)的绝对路径: System.out.println(getServletContext().getRealPath("")); ...
- Halloc内存分配器
MAX_NSBS 8192:默认的最大superblocks数量 SB_SET_SZ(MAX_NSBS / WORD_SZ):superblock set的大小,每个set32个superblcoks ...
- zsh 简单介绍
什么是 zsh,要想解释好这个问题,那么得先说明什么是 shell.不负责任的解释说法就是 shell 就是一个壳.这个壳可不是蜗牛的壳,而是计算机的一个壳,当然也不是计算机的外壳啦,这个壳是相对于计 ...
- HTMLElement
参考文档:MDN HTMLElement 一.继承关系 所有HTML元素都是由HTMLElement或者其更具体的子类型来表示的. HTMLElement继承自Element,并实现了GlobalEv ...
- swig编译GDAL的C#库时遇到的代码安全问题及解决方法
之前一直用的是别人编译好的gdal库开发,今天自己编译了gdal的2.0.0版本,踩了不少坑,但总算解决了. 编译方法主要参考http://blog.csdn.net/liminlu0314/arti ...
- [SinGuLaRiTy] 树形存储结构阶段性测试
[SinGuLaRiTy-1011] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. G2019级信息奥赛专项训练 题目 程序名 时间 内存 ...
- 【Egret】实现web页面操作PC端本地文件操作
Egret 实现web页面操作PC端本地文件操作: http://edn.egret.com/cn/book/page/pid/181 //------------------------------ ...
- instance 网卡是如何被拉起来的?- 每天5分钟玩转 OpenStack(172)
instance 的网卡是如何被配置并拉起的?这是理解和用好 cloud-init 非常关键的一步.我们先讨论一个最简单基础的场景:镜像中没有安装 cloud-init. 此时 instance 启动 ...