Javascript类型

51 阅读5分钟

1.数据的六种基本类型

  1. number 数值类型
  2. string 字符串
  3. boolean 布尔型
  4. object 对象
  5. null 空,无表示不存在,当为对象的属性赋值为null,表示删除该属性
  6. 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() 将字符串转换为浮点数