详解引用赋值操作符

详解引用赋值操作符

JavaScript的堆栈

JavaScript的内存大致被分为两块,一块是栈区,一块是堆区

栈区里存放的是函数的栈帧,以及里面的临时变量

堆区则是放的对象,比如数组对象, 文件对象.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jHvHL13U-1649680956849)(C:\Users\31932\AppData\Local\Temp\1649678046306.png)]

=赋值操作符的使用与其返回值

A = B 表示将B的值赋给A

同时这个语句会返回一个B的值

		var a = 10;
		var b;
		console.log(b=a); //10
		console.log(b); //10

如果B是一个引用数据类型,则会返回其堆区的地址

console.log则会根据地址直接找回堆区

windows对象在JavaScript的特殊性

		      function fun() {
		         a = b = 5;
		      }
		      fun();
		      console.log(a, typeof a); //5 number
		      console.log(b, typeof b); //5number
			  b=3;
			  console.log(b, typeof b); //3 number
			  var b = 114514;
			  console.log(b);//114514

在c语言中,这样的代码是会报错的,因为a,b都是定义在函数内部的局部变量,为什么可以在全局中打出来呢?

因为script是属于windows全局对象里的一个属性,如果我们在函数内部声明了一个当前script里没有的变量,JavaScript就会默认在全局中创建这样一个变量,因此他就可以访问了

		      function fun() {
		         a = b = 5;
		      }
		      //在全局创建一个 a 一个 b
		      fun();
		      console.log(a, typeof a);
		      console.log(b, typeof b);
			  b=3;
			  //修改b
			  console.log(b, typeof b);
			  var b = 114514;
			  //如果我们主动声明了,就会删除原来的b,创建一个新b
			  console.log(b);

连等表达式的处理

				  var a = 2;
			      function fun(a) {
			          a = b = 5;
			          console.log(a, typeof a);
			      }
			      fun();
			      console.log(b, typeof b);
			      console.log(a,typeof a);

对于图上代码 f(a) =g(b) = h(c)的情况下,我们的规定是从左享向右处理

先处理f(a)中的东西,并将a挂起,再处理b的东西,再将b挂起,再处理c的东西,拿到c的返回值,赋值给b,再根据A=B的返回值特点将c的返回值再赋值给A

注意,一步一步来,分段处理,从左向右走!!!

				var a = 2;
		      function fun(a) {
		          a = b = 5;
		          //先创一个A全局变量,a =等待赋值
		          //再创建一个b变量 b = 等待赋值
		          //5不需要执行
		          //执行赋值语句b 的值为5
		          //赋值语句执行结束,返回一个右操作数的值 5
		          //执行赋值语句,a的值变为5
		          console.log(a, typeof a);
		      }
		      fun();
		      console.log(b, typeof b);
		      console.log(a,typeof a);

引用数据类型的连等表达式处理

		var a = {n:1};
		var b = a;
		a.x = a = {n:2};
		console.log(a);
		console.log(a.x);
		console.log(b);

首先我们要,先知道对于一个{n:1}表示再堆区开辟对象,同时返回这个对象的地址。

现在我们逐步推进代码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bod5ChkX-1649680956850)(C:\Users\31932\AppData\Local\Temp\1649679233823.png)]

一开始我们的栈区和堆区都是空的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AVFY1kSs-1649680956851)(C:\Users\31932\AppData\Local\Temp\1649679293452.png)]

第一条语句在堆区创建对象,并把他的地址赋值个在栈区新建的a;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vIrHDAv2-1649680956851)(C:\Users\31932\AppData\Local\Temp\1649679325412.png)]

第二条语句在栈区新建一个b,把a里的值赋给他

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RQVc1iWQ-1649680956852)(C:\Users\31932\AppData\Local\Temp\1649679470699.png)]

从左向右执行,先执行a.x,通过a里存的地址找到堆区的对象,在里面新建一个x属性,赋值为undefined

在执行 a,无事发生!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7KIMl5Gj-1649680956852)(C:\Users\31932\AppData\Local\Temp\1649679580361.png)]

在执行{n:2} 在堆去新建一个对象,他地址是0x5678

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lmhs9Utp-1649680956852)(C:\Users\31932\AppData\Local\Temp\1649679642874.png)]

开始执行赋值操作,把{n:2}的返回值—他的地址赋值给a,同时结束了赋值操作,返回等号右边的值0x5678

注意

最关键的一步来了,现在我们开始执行这个赋值表达式

因为上一步在执行f(a) : a.x 的时候,本是上是对这个式子进行了处理

这时这个赋值指针指向的是 前面找到的0x1234里的x属性

这时候把x属性赋值为 0x5678这个返回值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C0SQabEs-1649680956853)(C:\Users\31932\AppData\Local\Temp\1649680502790.png)]

现在执行第一条输出语句

console.log(a)

找出a对应的对象 0x5678

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KmdQfrtj-1649680956853)(C:\Users\31932\AppData\Local\Temp\1649680593682.png)]

再执行第二个语句

console.log(a.x)

因为a里没有x属性,所以返回默认值undefined

最后执行

console.log(b)

找出b对应的对象0x5678

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ajw0lTiU-1649680956854)(C:\Users\31932\AppData\Local\Temp\1649680720064.png)]

0956853)]

再执行第二个语句

console.log(a.x)

因为a里没有x属性,所以返回默认值undefined

最后执行

console.log(b)

找出b对应的对象0x5678

​ [外链图片转存中…(img-ajw0lTiU-1649680956854)]

完成啦!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值