JavaScript 的类型

JavaScript 对象 
除了数字、字符串、布尔值、null、undefined(都不可变)这5种简单类型,其他都是对象。

javascript 存在2套类型系统,一套是元类型,用typeof可以检验,有六种:"number"、"string"、"boolean"、"object"、"function"、"undefined"。

另一套是对象类型系统,是元类型object的一个分支。

基础类型是通过传值来操作,而引用类型则是通过传址来操作的

JavaScript中的对象是可变的键控集合(keyed collections)。 
对象是属性的容器,其中每个属性都拥有名字和值。 
JavaScript中的对象是无类别的(class-free)的。它对新属性的名字和值没有约束。 
JavaScript包括一个原型链特性,允许对象继承另一对象的属性。

引用: 
对象通过引用来传递,他们永远不会被拷贝。

原型: 
每个对象都连接到一个原型对象,并且它可以从中继承属性。所有通过对象字面量创建的对象都连接到Object.prototype这个JavaScript中的标准对象。 
原型连接在更新时不起作用。我们对某个对象做出改变时,不会触及到该对象的原型。原型连接只有在检索值时才会被用到。

基础类型是通过传值来操作,而引用类型则是通过传址来操作的

包装类,以及“一切都是对象”。

typeof——看上去很官方

typeof是JS语言中的一个运算符,从它的字面来看,显然它是用来获取类型的,按JavaScript标准的规定,typeof获取变量类型名称的字符串表示,他可能得到的结果有6种:string、bool、number、undefined、object、function,而且JavaScript标准允许其实现者自定义一些对象的typeof值。

在JS标准中有这样一个描述列表:


Type


Result


Undefined


"undefined"


Null


"object"


Boolean


"boolean"


Number


"number"


String


"string"


Object (native and doesn‘t implement [[call]])


"object"


Object (native and implements [[call]])


"function"


Object (host)


Implementation-dependent

instanceof——原型还是类型?

instanceof的意思翻译成中文就是"是……的实例",从字面意思理解它是一个基于类面向对象编程的术语,而JS实际上没有在语言级别对基于类的编程提供支持。JavaScript标准虽然只字未提,但其实一些内置对象的设计和运算符设置都暗示了一个"官方的"实现类的方式,即从把函数当作类使用,new运算符作用于函数时,将函数的prototype属性设置为新构造对象的原型,并且将函数本身作为构造函数。

所以从同一个函数的new运算构造出的对象,被认为是一个类的实例,这些对象的共同点是:1.有同一个原型 2.经过同一个构造函数处理。而instanceof正是配合这种实现类的方式检查"实例是否属于一个类"的一种运算符。猜一猜也可以知道,若要检查一个对象是否经过了一个构造函数处理千难万难,但是检查它的原型是什么就容易多了,所以instanceof的实现从原型角度理解,就是检查一个对象的[[prototype]]属性是否跟特定函数的prototype一致。注意这里[[prototype]]是私有属性,在SpiderMonkey(就是Firefox的JS引擎)中它可以用__proto__来访问。

原型只对于标准所描述的Object类型有意义,所以instanceof对于所有非Object对象都会得到false,而且instanceof只能判断是否属于某一类型,无法得到类型,但是instanceof的优势也是显而易见的,它能够分辨自定义的"类"构造出的对象。

instanceof实际上是可以被欺骗的,它用到的对象私有属性[[prototype]]固然不能更改,但函数的prototype是个共有属性,下面代码展示了如何欺骗instanceof

function ClassA(){};

function ClassB(){};

var o = new ClassA();//构造一个A类的对象

ClassB.prototype = ClassA.prototype; //ClassB.prototype替换掉

alert(o instanceof ClassB)//true 欺骗成功 - -!

Object.prototype.toString——是个好方法?

Object.prototype.toString原本很难被调用到,所有的JavaScript内置类都覆盖了toString这个方法,而对于非内置类构造出的对象,Object.prototype.toString又只能得到毫无意义的[object Object]这种结果。所以相当长的一段时间内,这个函数的神奇功效都没有被发掘出来。

在标准中,Object.prototype.toString的描述只有3句

1. 获取this对象的[[class]]属性

2. 通过连接三个字符串"[object ", 结果(1), 和 "]"算出一个字符串

3. 返回 结果(2).

显而易见,Object.prototype.toString其实只是获取对象的[[class]]属性而已,不过不知道是不是有意为之,所有JS内置函数对象String Number Array RegExp……在用于new构造对象时,全都会设定[[class]]属性,这样[[class]]属性就可以作为很好的判断类型的依据。

因为Object.prototype.toString是取this对象属性,所以只要用Object.prototype.toString.call或者Object.prototype.toString.apply就可以指定this对象,然后获取类型了。

Object.prototype.toString尽管巧妙,但是却无法获取自定义函数构造出对象的类型,因为自定义函数不会设[[class]],而且这个私有属性是无法在程序中访问的。Object.prototype.toString最大的优点是可以让1和new Number(1)成为同一类型的对象,大部分时候二者的使用方式是相同的。

然而值得注意的是 new Boolean(false)在参与bool运算时与false结果刚好相反,如果这个时候把二者视为同一类型,容易导致难以检查的错误。

总结:

为了比较上面三种类型判断方法,我做了一张表格,大家可以由此对几种方法有个整体比较。为了方便比较,我把几种判断方式得到的结果统一了写法:


对象


typeof


instanceof


Object.prototype.toString


标准


"abc"


String


——


String


String


new String("abc")


Object


String


String


Object


function hello(){}


Function


Function


Function


Object


123


Number


——


Number


Number


new Number(123)


Object


Number


Number


Object


new Array(1,2,3)


Object


Array


Array


Object


new MyType()


Object


MyType


Object


Object


null


Object


——


Object


Null


undefined


Undefined


——


Object


Undefined

事实上,很难说上面哪一种方法是更加合理的,即使是标准中的规定,也只是体现了JS的运行时机制而不是最佳使用实践。我个人观点是淡化"类型"这一概念,而更多关注"我想如何使用这个对象"这种约束,使用typeof配合instanceof来检查完全可以在需要的地方达到和强类型语言相同的效果。

附1 IEEE 754 规定的双精度浮点数表示(来自中文wikipedia):

sign bit(符号): 用来表示正负号

exponent(指数): 用来表示次方数

mantissa(尾数): 用来表示精确度

JavaScript 的类型,布布扣,bubuko.com

时间: 2024-08-11 05:06:02

JavaScript 的类型的相关文章

JavaScript的类型自动转换高级玩法JSFuck

0 前言 最开始是不小心在微信公众号(程序员大咖)看到一篇JS的高逼格代码,然后通过里面的链接跳转到了JSFuck的wiki,就像顺着迷宫找宝藏的感觉,感叹JS的自动类型转换的牛逼. 1 样例 (!(~+[])+{})[--[~+""][+[]]*[~+[]] + ~~!+[]]+({}+[])[[~!+[]]*~+[]] //如何装逼用代码骂别人SB (([][[]]+[])[+!![]]+([]+{})[!+[]+!![]])//如何用代码优雅地证明自己NB 2 原理 1.对于非原

JavaScript事件类型

JavaScript事件类型 Web浏览器中可能发生的事件有很多类型.这里我将主要将下面几种常用的事件类型: UI事件 焦点事件 鼠标与滚轮事件 键盘与文本事件 复合事件 变动事件 HTML5事件 设备事件 触摸与手势事件 第一部分:UI事件 UI事件中UI即(User Interface,用户界面),当用户与页面桑拿的元素交互时触发. UI事件中主要包括load,unload,abort,error,select,resize,scroll事件. 1.load事件 此事件为当页面完全加载完之后

javascript 操作符类型隐性转换

(一).一元操作符只能操作一个值的操作符叫做一元操作符1.递增和递减操作符a. 在应用于一个包含有效数字字符的字符串时,先将其转换为数字值,再执行加减1的操作.字符串变量变成数值变量.eg: var a='1'; ++a;  //a 变成2b.在应用于一个不包含有效数字字符的字符串时,将变量的值设置为NaN,字符串变量变成数值变量.eg:var a='1aa';++a  //a 变成NaNc:在应用于布尔值false时,先将其转换为0再执行加减1的操作.布尔值变量变成数值变量.eg:var a=

javascript不同类型对象比较规则

javascript不同类型对象比较规则 例子一: [0]==true; 首先会把true进行toNumber,结果为1,式子及转化为 [0]==1 然后[0]会被toString(),结果为"0",式子转化为"0"==1 接着"0"会被toNumber(),结果为0,式子转化为0==1 最后根据type(x)==type(y),式子转化为0===1 所以[0]==true会得到false 例子二: "potato"==tru

JavaScript中类型检测

JavaScript是类型松散的,也就是说,在使用变量和函数参数之前,不会对它们进行比较已确保它们的数据类型正确. JS有五种基本数据类型:Undefined.Null.Boolean.Number和String,还有一种复杂数据类型Object. JS是不支持任何创建自定义类型的机制,所有值最终都将是上述6种数据类型之一. 对于上述6种类型的变量,可以利用typeof操作符来检测. typeof操作符可能返回下列六个字符串: "undefined"--这个值未定义,对应Undefin

Javascript对于类型的理解

1.instanceof和typeof区别 两者都是用来判断类型用的,instanceof顾名思义,是否是某一类型的实例,这个返回值是bool值,例如(new String("so") instanceof String) typeof返回值则是类型名,如(typeof 'so') Javascript对于类型的理解

JavaScript对象类型详解

JavaScript对象类型详解 JavaScrtip有六种数据类型,一种复杂的数据类型(引用类型),即Object对象类型,还有五种简单的数据类型(原始类型):Number.String.Boolean.Undefined和Null.其中,最核心的类型就是对象类型了.同时要注意,简单类型都是不可变的,而对象类型是可变的. 什么是对象 一个对象是一组简单数据类型(有时是引用数据类型)的无序列表,被存储为一系列的名-值对(name-value pairs).这个列表中的每一项被称为 属性(如果是函

Javascript 值类型和引用类型

本篇文章由:http://xinpure.com/javascript-value-types-and-reference-types/ Javascript变量类型 值类型: 字符串.数字.布尔.Null.Undefined 引用类型: 数组.对象.函数 值类型与引用类型的比较 通过两个实例来比较这两种类型 (调试环境: Chrome 开发者工具 Console) 值类型实例 var a = 'hello'; var b = a; b; /* hello */ a = 'world'; b;

面向对象的JavaScript --- 动态类型语言

面向对象的JavaScript --- 动态类型语言 动态类型语言与面向接口编程 JavaScript 没有提供传统面向对象语言中的类式继承,而是通过原型委托的方式来实现对象与对象之间的继承. JavaScript 也没有在语言层面提供对抽象类和接口的支持. 正因为存在这些跟传统面向对象语言不一致的地方,我们在用设计模式编写代码的时候,更要跟传统面向对象语言加以区别.我们有必要先了解一些 JavaScript 在面向对象方面的知识. 编程语言按照数据类型大体可以分为两类,一类是静态类型语言,另一