1.数据的六种基本类型
- number 数值类型
- string 字符串
- boolean 布尔型
- object 对象
- null 空,无表示不存在,当为对象的属性赋值为null,表示删除该属性
- undefined 未定义,当声明变量却没有赋值时会显示该值,可以为变量赋值undefined
7. ES6 中增加了symbol
2. 数值类型
值类型 :原始数据或原始值,存储在栈中,数据存储在变量被访问的位置
介绍:值类型占据的空间都是固定的,所以可以把他们存储在狭窄的内存栈区,这种存储方式更方便计算机进行查找和操作,所以执行速度会非常快,在JS中 number,string,boolean,undefined属于值类型
引用类型:存储在堆中,堆中存储的一般是对象,然后通过一个编号传递给栈内变量,这个编号就是所谓的引用指针.
介绍:因为其大小不固定,不能分配到栈区,只能被分配到堆区,如果存储在栈区,会降低计算机的寻址速度,而堆区的空间不固定很适合存储大小不固定的对象数据。然而在栈区存储对象在堆区的地址即可,而地址的大小是固定的,所以这种分离存储的方法不会影响
计算机的寻址速度,对变量的性能也没有任何负面影响。在JS中 object型数据包括function,array属于堆区
下表:是值类型和数据类型的比较:
栈
堆
管理方式
由编译器管理
由程序员管理
空间大小
固定,一般比较小
不固定,一般比较大
垃圾问题
没有垃圾
容易产生数据碎片
生长方向
向下
向上,即向着内存增加的方向
分配方式
静态和动态分配
动态,无静态分配
执行效率
由系统提供底层支持,有专门寄存器存放栈地址,效率高
由库函数提供支持,效率低
注意:Js把字符串作为值类型进行处理,不过,字符串在复制和传递运算中,是以引用型数据的方法来处理的
值的操作:
复制值:即把值赋值给新变量,或是通过变量把值赋值给另一个变量、属性或是数组元素
原始值:在赋值语句中,操作过程将会产生一个实际值的副本,副本的值和实际值之间没有任何联系,他们独自位于不同的栈区或堆区
引用值:在赋值语句中,所赋的值是对原始值的引用,不是原值的副本,更不是原值本身
传递值:即把值作为参数传递给函数获方法
原始值:把值传递给函数或方法时,传递的仅是副本,而不是值本身
引用值:传递给函数获方法是对原始值的引用
比较值:即把值和另一个值进行比较,看是否相等
原始值:在进行原始值比较时,进行逐字节的比较来判断他们是否相等,比较的是值本身而不是值所处的位置,固然比较的结果会可能 会相等,但只是说明他们包含的字节信息是相同的
引用值:比较的是两个引用地址
注意:值类型数据 常称之为原始值或基本值,引用型数据常称之为引用值或复合值
1.3 数据类型的检测
typeof 运算符,对原始值检测比较有效,对对象和数组,返回值都是“object”
console.log(typeof(1)) // number
console.log(typeof({})) //object
console.log(typeof([])) // object
console.log(typeof("")) //string
console.log(typeof(function(){})) //function
console.log(typeof(true)) //boolean
console.log(typeof(null)) // object
console.log(typeof(undefined)) //undefined
constructor 属性 ,JS对象自带的属性,这个属性也被称之为构造函数属性,该属性值引用的是原来构造该对象的函数
[].constructor Array
{}.constructor Object
/1/.constructor RegExp
该属性可以判断对象的类型
instanceof 只能判断两个对象是否属于实例关系,而不能判断一个对象实例具体属于哪种类型
[] instanceof Array true
[] instanceof Object true
[] instanceof Date false
有没有更安全,更好的方法呢?肯定是有的
探索:不同类型对象的toString() 返回值,Object对象定义的toString() 方法返回的字符串形式总是 [object class],object表示通用类型,class表示对象的内部类型,如:Array对象的class为“Array”,所以我们可以用这个方法来进行数据类型的判定
更安全的数据类型检测:
确定了使用Object.prototype.toString()方法来检测,那如何利用的?
1.首先 Array,Boolean,Number等都是Object的实例,可以使用 instanceof 来检测,所以我们可以得知,Array等都复写了toString的方法,但我们想让你调用Object的toString方法,怎么办呢?
2. 第一种方法:先删除Array等的toString方法,使用delete Array.prototype.toString(),然后在调用[].toString()
delete Array.prototype.toString;
[].toString(); //[object Array]
3.第二种方法:使用 call() , Object.prototype.toString.call(obj)
Object.prototype.toString.call([]) //[object Array]
那为什么要用call呢,当然apply也可以
首先我们要改变函数内部指针即Object.prototype.toString函数内部的指针,也就是这个函数的所有者,所以我们使用call (不明白的轻多翻翻作者的文章,都有详细介绍)
所以我们可以这样封装:
function typeOf(obj) {
const toString = Object.prototype.toString;
const map = {
'[object Boolean]' : 'boolean',
'[object Number]' : 'number',
'[object String]' : 'string',
'[object Function]' : 'function',
'[object Array]' : 'array',
'[object Date]' : 'date',
'[object RegExp]' : 'regExp',
'[object Undefined]': 'undefined',
'[object Null]' : 'null',
'[object Object]' : 'object'
};
return map[toString.call(obj)];
};
1.4数据类型的转换
Js能够自动转换变量的数据类型,这种转换是一种隐性的行为,如下表:
隐式转换
值
字符串操作环境
数字操作环境
逻辑运算操作环境
对象操作环境
undefined
"undefined"
NaN
false
Error
null
"null"
0
false
Error
非空字符串
不转换
字符串对应的数字值
NaN
"NaN"
不转换
false
Number
空字符串
不转换
0
false
String
0
"0"
不转换
false
Number
其他所有数字
"数字的字符串值"
不转换
true
Number
true
"true"
1
不转换
Boolean
false
"false"
0
不转换
Boolean
转换函数
- parseInt() 将字符串转换为整数
- parseFloat() 将字符串转换为浮点数