js数据类型
基本类型
因为我们可以操作保存在变量中的实际的值,所以这些类型是按值访问的
- String
- Number
- Boolean
- Null
- Undefined
引用类型
引用类型的值是保存在内存中的对象
在操作对象时,事实上是在操作对象的引用,而不是实际的对象
因此可以说引用类型的值是按引用访问(地址指针)
- Object
# Undefined 类型
Undefined 类型只有一个值——undefined
值得注意的是:包含 undefined 值的变量与尚未定义的变量还是不一样的,如下
|
但如果对 age(未声明变量) 使用 typeof 的话,也会返回 undefined
# Null 类型
类似 Undefined,Null 类型也是只有一个值——null。
null表示一个空对象指针,因此当使用 typeof null 时,会返回“object”
事实上,undefined 是派生自 null 值得,因此有如下判断时返回 true
|
只要意在保存对象的变量还没有真正保存对象,就应该明确地让该变量保存 null 值。
这样做不仅可以体现 null 作为空对象指针的惯例,而且有助于进一步区分 null 和 undefined。
typeof 操作符
typeof 可以检测原始值类型,也就是基本类型。
但是,但基本类型,在相同值的情况下,如果是利用构造函数来定义的话,typeof 返回的结果都只会是 object
因此,typeof 具有局限性。
typeof 只有一个实际的应用——检测一个对象是否已经定义或者是否已经赋值。而不是检查对象的类型。
instanceof 区别引用类型
对于引用类型的数据,单纯使用 typeof 是无法达到目的的。所以,要用 instanceof 操作符来区别数组、函数和对象
但 instanceof 也有它严重的局限性:不能跨帧使用。
假设一个浏览器帧A(frame A)里的一个对象被传入到帧B(frame B)中,两个帧中都定义了 Person 构造函数,如果来自帧A 的对象是帧A 中Person的实例,则有:
因为每个帧都有 Person 的拷贝,它被认为是该帧中的Person的拷贝实例,尽管两个定义是一样的。
同样的问题也出现在其他两个非常重要的内置类型中:数组和函数,所以检测这两个内置类型一般不用 instanceof。
而且 instanceof 对于对象的整个原型链都能检测到,例如:
因此,用 instanceof 检测某一对象是否属于特定类型并非最佳。
仅仅用来比较来自同一个 JavaScript 上下文的自定义对象。正如 typeof 一样,避免其他的用途。
使用内置对象的 class 属性来判断
使用 Object.prototype.toString.call() 来判断
[[Class]]是一个内部属性,所有的对象(原生对象和宿主对象)都拥有该属性,通过该属性的值可以用来判断一个原生对象属于哪种内置类型,而这个属性只能通过Object.prototype.toString 方法来访问
在 ES5 中,对于 toString() 方法被调用时,执行的步骤如下:
- 如果this的值为undefined,则返回”[object Undefined]”
- 如果this的值为null,则返回”[object Null]”
- 让O成为调用ToObject(this)的结果
- 让class成为O的内部属性[[Class]]的值
- 返回三个字符串”[object “, class, 以及 “]”连接后的新字符串
所以判断变量类型的方法可以如下: