JavaScript数据类型
数据类型
JavaScript
中有两种数据类型:原始类型和引用类型原始类型:原始值直接存储在变量的内存中
引用类型:变量中存储的为一个指针,指向对象在内存中的实际地址
原始类型
JavaScript
中的基本数据类型有5中:boolean
、number
、string
、null
、undefined
es6
中新增一种基本类型symbol
原始类型的判别
鉴别原始数据类型可以使用typeof
,它可以被用在任何变量上,并返回一个说明数据类型的字符串。
通常在实际判断时,typeof
只用于字符串、数字、布尔和未定义类型。null
的判断不要使用。
conso.log(typeof null) // 'object'
这是错误操作,可以理解为null
中为指向空对象的指针
原始类型的方法
字符串和数字拥有方法,可以方便我们进行操作,但是这并不意味着他们是对象,这涉及原始封装类型的问题。
不可变性
JavaScript
中,字符串和数字具有不可变性,当创造完成后值便不会被改变,只能通过重新赋值的方法来改变变量值,因此对应的字符串和数组方法会返回一个新的字符串或数字而不是在原有变量上做改动。
引用类型
JavaScript
中的引用类型就是指的对象,对象是属性的无序列表,属性包含键(始终为字符串)和值,如果一个属性的值为函数,那么该属性即为方法。
对象的创建
var obj = new Object()
obj2 = obj
第一行代码将创建一个通用对象,并将指向该对象的指针保存在变量obj
中,这是引用类型与原始类型的一个基本差别,而obj2 = obj
也只是将该指针复制一份给变量obj2
。
对象创建可以使用字面量形式,虽然并没有调用new Object()
,但是JavaScript
引擎在背后做的工作在这两种不同方式下是一样的
引用解除
当大量使用对象时候,如果我们不再使用某一对象,可以手动将其释放
obj = null
当内存中的对象不再被引用后垃圾收集器会将其释放掉。
内置对象
Obiect
只是内置对象其中之一,JavaScript
中还有其他特殊用途的内置对象
对象名 | 说明 |
---|---|
Array | 数组类型,以数字为索引的一组值的有序列表 |
Date | 日期和事件类型 |
Error | 运行期错误类型(还有其他错误子类型) |
Function | 函数类型(函数本质也是对象,这会帮助理解许多问题) |
Object | 通用对象类型 |
RegExp | 正则表达式类型 |
访问属性
访问属性可以通过.
、[]
两种方式。中括号可以允许使用变量而不是字符串字面量形式来访问,而且允许属性名中出现特殊字符。
引用类型的鉴别
-
函数类型的鉴别可以使用
typeof
操作符,此时会返回function
,因为函数存在[[call]]内部属性,存在该属性就会被判断为函数。 -
其他引用类型可以使用
instanceof
操作符。该操作符可以鉴别继承类型,这意味着所有对象都是Object
的实例,使用该操作符时会返回true
,
var arr = []
var obj = {}
function f () {}
arr instanceof Array / true
arr instanceof Object / true
f instanceof Function / true
f instanceof Object / true
数组的鉴别
一个页面允许存在多个框架,此时如果数组在多个框架间传递,因为上下文的以及其他标准不同的问题会使得instanceof
操作符无法判断数组,此时可以使用Array.isArray(数组名)
来进行数组的判断
原始封装类型
为了便于操作基本类型值,ECMAScript还提供了3个特殊的引用类型: Boolean、Number、String。这些类型与其他内置对象类型相似,但同时具有各自的基本类型相应的特殊行为。
实际上,每当读取一个基本类型值得时候,后台就会创建一个对应的基本包装类型的对象,从而让我们能够调用一些方法来操作这些数据。包装类型,是一个专门封装原始类型的值,并提供对原始类型的值执行操作的API对象。
####原始封装类型的生命周期
普通的内置对象与基本包装类型的主要区别就是对象的生命期,使用new操作符创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内存中,而自动创建的基本包装类型的对象,则只是存在于一行代码的执行瞬间,然后立即被立即销毁。这意味着我们不能再运行时为基本包装类型值添加属性和方法,并且不能使用instanceof
操作符判断
####手动创建原始封装类型
var name = new String('aaa')
var boo = new Boolean(false)
typeof name /// Object
if(boo) /// 此时会被判定为正确
手动创建原始封装类型会带来许多负面效果。1、无法通过typeof
来判断数据类型。2、此时会被判定为对象,会影响if
语句的判断,因为对象会被判定为true