js 引用值和原始值

数据类型

js将数据类型分为两种:
1. 原始类型
原始类型有: Number、String、Boolean、Undefined、Null,Symbol(es6)类型。
原始值是大小固定简单的数据段,也就是说数据的大小不会发生变化,并且不能由其他值组成。

Number: 数字类型,1、1.1、-1等等,js中数字类型就包括了浮点型。

String: 字符串类型,带有一对单引号(’ ')或双引号的值(" "),表示字母、符号、数字的统称。比如,我们要输入中文必须但引号: “你好世界”。

Boolean: 布尔类型,只有两个值true(真) or false(假),表示一种状态,代表电路的0或1.

Undefined: 未定义类型,如果变量没有赋值,则变量默认就是undefined,相当于是变量的默认值。

Null(空): 占位,表示一个没有引用的对象,比如一个对象var obj = new Object();比如说不要这个对象了,可以用null表示空引用。

Symbol: es6新增,表示独一无二的值。

2. 引用类型
也叫复合类型,复杂(引用)值可以由很多不同类型的数据组成,引用值的大小在内存中是未知的,因为引用值可以包含多个值,而不是特定的已知值。

引用类型有: 数组(Array)、对象(Object)、函数(Function)等等

例如:
数组:正常变量是一个容器,它是一排容器,所以能存储多个值,相当于一次性申请了多个连续的内存空间一样。

var arr = [1,2,3,4,5,false,"abc"]

js是动态语言解释一行执行一行,因此在js里是由值决定变量的类型

//值是数字,因此变量的类型就是数字类型
var a = 10; 
//由于js是动态语言,所以可以改成其它类型值
a = 'hi';

堆和栈:

js引擎将内存划分为两种内存空间: 堆和栈,程序执行前,引擎会为数据分配内存空间,不同类型数据会分配到不同内存空间中。

栈存储
系统自动分配固定的内存,数据先进后出,像一个有底没顶的箱子,线性结构。由于原始类型数据的值是固定大小的,所以存放在栈中,方便查找。基本类型的值是按值访问的,因为可以操作保存在变量中的实际值。

在js中变量就是指向(标识)栈内存的位置,变量的位置就是栈内存的位置,变量名就表示栈内存的名字,当你声明一个变量时就会在栈内存中分配空间。

var a = 10;

以上代码会在栈内存中分配空间并命名为a

栈内存和栈内存之间的赋值是拷贝,一个变量向另一个变量赋值原始值时。,复制的是该值的一个副本。

var a = 10;
var b = a;

ab是原始值,首会在栈底依次申请a和b两个空间,然后引擎会取出a的值,拷贝一份给b,b的值是a的副本,a和b互不影响,不管改了哪个变量的值都不会影响到另一个变量的值。
在这里插入图片描述
原始值有个特点叫不可改变的原始值,就是一个内存空间已经存储值了,就不能在这个内存空间上改变数据值,而是开辟另一块内存并命名,而原来的内存空间的命名被擦除掉而找不到这个内存空间。

这就是我上面说的,栈是分配固定大小内存,赋予新值时,不可以在原来空间上覆盖数据,因为空间已经固定大小了,当你赋予新会重新分配空间。

var a = 10;
var b = a;
a = 20;
/*
	a重新赋值,会在开辟另一个内存空间并命名为a
	而原来的叫a的内存空间,会被擦除变量名。
*/

在这里插入图片描述

内存原理: 我们清理内存时,数据并没有被删除了,数据还在内存里,内存中删掉的数据只是清除标号,让这个空间找不到了,但是如果内存满了然后你在清理内存,把标号全部清除,系统会告诉你还有多少空间,其实这个数据还存在并没有清除,当你在存新东西的时候,新东西会覆盖旧的东西(二次覆盖),这个时候数据是真被删除了,所以我们想删除数据时,多往内存存东西就行了。

堆存储
系统动态分配内存,像一个书架,怎么拿怎么放,散列结构。引用值是指由多个数据值组成的对象,值大小未知,因此存储在堆中,由于js不允许直接访问堆中的位置,因此栈中会存储该对象在堆中的引用地址(引用地址的大小是固定的),指向堆中的对象。在访问时,会通过栈中存储的引用地址找到堆中的对象。

下面的代码会发以下操作:
1.首先会栈中申请一个空间并命名为arr。
2.当引擎读到[1,2],会将其存放在堆中。
3.栈中的arr会存放[1,2]在堆中的引用地址。
4.当读取[1,2]时,会通过栈中存储的引用地址找到[1,2]。

var arr = [1,1];
console.log(arr[0]);

在这里插入图片描述

当一个变量向另一个变量赋值引用值时,复制的是地址,因为不能直接操作堆中的数据,所以只能复制地址,因此arr1和arr都指向[1,2],该从一个变量改变值,另一个变量的值也会受到影响,arr重新赋予引用值,指向了新的空间。

var arr = [1,2];
var arr1 = arr;
arr = [1,3];
document.write(arr1) //1,2

在这里插入图片描述

我们可以得出一个结论,在js中可以直接访问栈内存的位置,因此可以直接操作原始值,而不能直接访问堆内存中的位置,所以只能通过引用地址间接访问引用值,所以说原始值可以按值访问,而引用值只能是按引用地址访问。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值