javascript中的数据类型

1. 数据类型
javascript中包含6种数据类型:undefined、null、string、number、boolean和object。其中,前5 种是原始数据类型,object是对象类型。

object类型中包括Object、Function、String、Number、Boolean、Array、Regexp、Date、 Globel、Math、Error,以及宿主环境提供的object类型。


2. 类型判断
通常在javascript中进行类型判断主要通过3种方式:typeof、instanceof、constructor。

2.1 typeof
typeof操作可能返回的类型为undefined、object、number、string、function、boolean。但是会有一些情况并不能完全判断准确。比如typeof new String('')的值为object。

2.2 constructor
有 时候我们可能会很偷懒的使用a.constructor == String进行类型判断,但是constructor其实是不靠谱的东西。因为当我们调用a.constructor的时候,内部操作其实是 ToObject(a).prototype.constructor(ToObject是什么,看下文分解)。

看下面一段代码就能明白:

String.prototype.constructor=Number;
alert('test'.constructor == String); //Result:false

或者

function MyClass() {
}
MyClass.prototype = {};
alert((new MyClass).constructor == MyClass); //Result:false

而且,通过constructor并不能判断出对象实例类型的继承关系。因为javascript的继承其实是通过原型链实现的(原型链是什么,看下文分解)。

另外,null.constructor会抛出运行时的TypeError,所以使用constructor除了不靠谱外,还可能伴随着异常的风险。

2.3 instanceof
例子:a instanceof String

关于object类型的判断,使用instanceof判断是比较靠谱的方法。instanceof所做的事情是,先取出类型对象(String) 的prototype成员(String.prototype),然后和要判断类型的对象(a)的原型链中的对象逐个比较。当发现是一个对象的时候返回 true,原型链中当前节点是null的时候返回false。

类型判断示例:判断一个变量是否是字符串类型

function isString(str) {
    return (typeof str == 'string' || str instanceof String);

}


3. 类型转换
ecma262中描述了以下几种类型转换的操作:

ToNumber:转换成number型
ToString:转换成string型
ToBoolean:转换成boolean型
ToObject:转换成object型
ToPrimitive:转换成原始类型
每种操作都描述了从什么类型转换成该类型的映射。比如上文的'a'.constructor中,就包含解析器使用ToObject将‘a’转换成 object的一个隐式操作。

这 里想要主要说的是ToPrimitive。ToPrimitive用于转换成原始数据类型。当要转换的量已经是原始类型时,会直接返回。如果要转换的是一 个Object,那会调用[[DefaultValue]]方法做转换。([[DefaultValue]]是什么,下文分解)该方法可以传入一个 hint参数,说明需要将Object转换成字符串或数字。如果要转换成字符串,则调用Object的toString方法,如果要转换成数字,则调用 Object的valueOf方法。具体在运行时什么时候应该转换成什么类型,请参考ecma262中关于expression的描述部分。


4. Object
除了5种原始类型外,一切都是Object,包括Object、Function、Array等等,他们的实例和构造器,都是Object。那 Object是一个什么东西呢?

Object是一个:无序的成员集合

它是一个集合,说明它包含0-n个成员。而它是无序的。

每一个成员由以下3个部分组成:名称、值、特征集合

下面的代码中:

var obj = {'key': 'value'};
key就是成员名称,value就是值,obj这个Object从代码上看起来包含了一个成员,注意,是从代码上看而已。这里我们不去深究它先。

那特征集合是个什么东西呢?

javascript的对象成员可能包含下面几种特征的0个或多个:ReadOnly、DontEnum、DontDelete、 Internal。

ReadOnly:拥有这个特征的成员是不能被程序修改的。
DontEnum:拥有这个特征的成员是不能被for in遍历的。
DontDelete:拥有这个特征的成员是不能被delete操作删除的。
Internal:代表这个成员是内部成员。通常内部成员不能被程序以任何方式访问,但是有些javascript的引擎实现将它以特殊方式暴露,使得可以访问对象的某些内部成员。
一个对象的Internal成员以[[xxxx]]的方式来表示。

下面列一些和本博有关的的Object可能包含的internal成员。

[[Class]]:表示该对象的类型。比如function Object的[[Class]]成员的值是"Function"
[[Get]](PropertyName):获取对象的属性值。
[[DefaultValue]] (Hint):用于ToPrimitive进行类型转换时调用。hint参数可能的值为"string"或"number"
[[Prototype]]: [[Prototype]]成员实现了javascript中所谓的“原型链”。一个对象的[[Prototype]]成员可能是object对象,或者 是null。只有Object.[[prototype]]为null,其他任何对象的[[Prototype]]成员都是一个Object
[[Call]]:function Object特有的成员,在函数被调用的时候,就是调用的[[Call]]。
[[Construct]]:function Object特有的成员,在函数作为构造器,被new操作符用于创建对象的时候,就是调用的[[Construct]]。
[[Scope]]:[[Prototype]]成员实现了javascript中所谓的“作用域链”。

 
原文地址:https://www.cnblogs.com/gaotianle/p/2794920.html