JS数据类型-基础知识

Posted wmui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS数据类型-基础知识相关的知识,希望对你有一定的参考价值。

JS类型系统

JS的类型系统包括原生对象、宿主对象和浏览器扩展对象

原生对象

原生对象分为原始类型和对象类型,原始类型分为空值和包装对象,对象类型分为构造器对象和单体内置对象

原始类型

空值:JS有两个空值,分别是undefined和null,逻辑上,undefined表示原始类型的空值,null表示对象类型的空值

包装对象:String、Number、Boolean三种

对象类型

构造器对象:Object、Function、Date、Array、Error和RegExp。

注意: 如果使用new构造器函数定义包装对象,那么包装对象也是构造器对象,如new String(\'hello\')

单体内置对象:Math、JSON、全局对象和arguments四种,它们不需要声明可以直接使用

宿主对象

宿主对象指在宿主环境下特有的对象,常见的宿主环境如浏览器、操作系统等,浏览器环境中的宿主对象有window、document、navigator等。

浏览器扩展对象

浏览器扩展对象是浏览器自己实现的对象,比如Debug对象,早期IE浏览器的ActiveXObject对象。

理解包装对象

上面提到的字符串String、数字Number、布尔值Boolean之所以称作包装对象,是因为在一定条件下会它们可以自动转化为对象。

包装对象是特殊的引用类型,当读取字符串、数值和布尔值的属性或方法时,创建的临时对象就是包装对象

以字符串为例,通过new String()的方式将其转换为包装对象,对象会继承字符串的属性和方法,当属性或方法引用结束,这个新建对象就会销毁。

var s = \'hello\'
var s2 = s.slice(3)
// 过程如下: 创建实例 调用方法 销毁实例
var s = new String(\'hello\')
var s2 = s.slice(3)
s = null

包装对象是引用类型,所以执行流离开当前作用域之前对象一直保存在内存中。

var s = new String(\'hello\')
s.name = \'wmui\'
alert(s.name) // wmui

包装对象的创建方式有两种:Object方式和构造函数方式

Object方式

var s = new Object(\'hello\')
var b = new Object(true)
var n = new Object(1)

构造函数方式

var s = new String(\'hello\')
var b = new Boolean(true)
var n = new Number(1)

用构造函数创建包装对象和调用转型函数的结果是不一样的,转型函数返回的是基本类型值,构造函数返回引用类型值

var s = \'hello\'
var s2 = String(\'hello\')
var s3 = new String(\'hello\')

console.log(typeof s, typeof s2, typeof s3) // string string object

相等运算符将原始值和包装对象视为相等,因为包装对象调用其valueOf()方法后,返回的原始值就是自身。但它们不是恒等的,因为它们的数据类型不同

var s = new String(\'hello\')
var s2 = \'hello\'

console.log(s == s2) // true
console.log(s === s2) // false

总结

重点就一句话,包装对象是特殊的引用类型

原始值和引用值

编程语言中,能够表示并操作的值的类型叫做数据类型,JS的数据类型分为原始类型(也叫基本类型或简单类型)和引用类型(也叫复杂类型)。原始类型包括String、Number、Boolean、Null、Undefined五种,引用类型就是Object。原始类型的值称作原始值,引用类型的值称作引用值。

原始值

原始值也叫简单值,是最简单的数据形式,所以它们是不可以再细化的。原始值的最大特点就是不可更改。

var s = \'hello\'
s.toUpperCase()
alert(s) // hello

引用值

引用值由JS对象组成(可以是多种不同类型的对象),和原始不同得是它的值是可以修改的,也正因为如此致使它在内存中占据的空间大小是未知的。

var o = {name: \'wmui\'}
o.name = \'hello\'
o.age = 10
console.log(o.name, o.age) // hello 10

存储方式

原始值由于其占据的内存空间是固定可计算的,为提升变量的查询速度将其存储在栈(stack)中。

引用值由于其大小可变,放在栈中会降低变量查询速度,所以它是在堆(heap)中存储的,存储在变量处的是一个指向堆中对象的指针。

访问方式

原始值引用它们时会在栈中创建一个新的值,所以改变原始值不会影响引用它们的值。

var s = \'hello\'
var s2 = s
s = \'world\'
console.log(s, s2) //world hello

引用值是一个指向对象的指针,当对象改变时,所有指向该对象的引用值也会改变。

var o = {name: \'wmui\'}
var o2 = o
var o3 = o2
o.name = \'hello\'
console.log(o.name, o2.name, o3.name) // hello hello hello

动态属性

原始值不能添加属性和方法。引用值可以添加、修改、删除属性和方法。

var s = \'hello\'
s.name = \'wmui\'
alert(s.name) // undefined
var o = {name: \'wmui\'}
o.age = 10
alert(o.age) // 10

总结

原始值在栈中存储,引用值在堆中存储
原始值不能动态添加属性,引用值可以动态添加属性
原始值引用时会创建一个副本,引用值创建一个指向对象的指针

以上是关于JS数据类型-基础知识的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript基础基础数据类型

JS基础-数据类型-运算符和表达式-变量和常量

JS基础--定义 数据类型 数学时间函数 数组

Relay.js 没有正确解析组合片段

01JavaScript基础——引入/输出方式变量数据类型运算符

[Go] 通过 17 个简短代码片段,切底弄懂 channel 基础