Vue中的变量赋值问题

 更新时间:2023年10月18日 10:13:07   作者:weixin_42693164  
这篇文章主要介绍了Vue中的变量赋值问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

Vue变量赋值

前些天写Vue项目遇见一个很有意思问题:

将一个数据(类型是对象)赋值给一个变量,当我去改变这个变量的时候,给它赋值的数据也跟着变化了,当我去改变数据时,变量也跟着变了,这让我想起了js中的浅复制和深复制,为验证,将对象(引用类型)改成字符窜(基本数据类型),果然,这个问题就不见了。

在js中有两种数据类型

(1) 基本数据类型:number、string、boolean、null、undefined、symbol(ES6)

(2) 引用数据类型:object、function(函数实际也是对象)

为何会分为这两种数据类型呢?

个人见解

在一段程序中必定会有这样的场景:

(1) 当一个方法执行完后,不再引用的变量会被销毁,被引用的变量不会被销毁,不会造成资源浪费和多余的性能消耗;

(2) 定义一个变量时,这个变量会被自动分到对应内存中(栈内存和堆内存),提高变量查询的速度;例如,定义一个未知大小的变量(如:对一个对象的增加删除),放在较小内存的栈中,栈大小是有默认值的,如果申请的临时变量太大的话就会超过栈大小,造成栈溢出,很明显会影响性能和查找速度。反之,如果一个固定大小的变量放到堆内存中,实际堆内存是可以申请大小的(相当于一个自适应的网页),只要不超出内存大小;很明显会造成资源利用不合理。

浅复制

将一个对象的变量赋值给另一个变量,修改其中一个变量时,另一个的值也会跟着变化,这就是浅复制,输出结果如下:

当将对象修改为字符串时,赋值给一个变量,修改其中一个值时,另一个并不会变化,如下:

为什么???

原来在Js中基本数据类型是直接按值存储在栈内存中的,而引用类型的值是存储在堆内存中的,Js代码都是自上而下的在栈内存中执行的(有一些资料显示,js并没有从严格意义上去区分栈和堆,在一些场景下也是有所区分的,例如:浅复制和深复制),那堆内存中的数据就没有用了吗???

可能是为了解决这个问题,在栈内存中给堆内存开辟一个专门用来放置它的地址,告诉js引擎,我在外面游荡,但是你可以通过这个地址找到我。

所以,这就可以想到,当我们直接将一个引用数据类型赋值给一个变量的时候,实际上只是在栈内存中执行复制了一下这个对象的地址,并不是这个对象实际的值,同一个地址指向的当然就是同一个值。

解决的方法:

既然知道了问题所在就要去干掉它,首先定一个目标:变量怎样获取到对象实际的值???

深复制

通过上面封装的方法在执行,如下:

问题解决了,实际上这是因为obj通过遍历将值都赋值给了变量obj1,obj1也是一个完整实体存在了,只是与obj相似而已,当然obj1在栈内存中也有了一个自己专属的地址,所以obj和obj1实际就不存在任何关联了。

深复制的方法有很多,介绍一种最常用的:

JSON.parse(JSON.stringify(obj))

个人理解:

这个实际就是利用JSON.stringify(obj)将对象的内容转换成字符串,那么在栈内存中就会给他一个空间存储,之后这个字符串想去外面的世界看看有多精彩,通过JSON.parse还原回原来的对象,带着家一起出走到了堆内存中,在栈内存中留下了联系方式(地址),从而实现了深复制。

注意:

JSON.parse(JSON.stringify(obj))不能复制函数类型,obj也是要可以枚举才行,在IE7以下浏览器会报错

对于js基本数据类型的赋值谈不上是深复制,因为每每声明一个变量时,栈内存中就会给其一个固定空间,如下面的a和b,实际他们两个都在各自的空间,空间里面都放着实际值,互不干扰。

Var a=1;
Var b=a;

番外

Null的数据类型实际是object类型,为何会在基本数据类型里面呢???

查看资料很多都说是一个将错就错的bug

实际想一下,很多关于提高性能的书里面都有提到一个“对象不用时就obj=null“,这是因为浏览器有一个垃圾回收机制,当检测到这原有的堆内存没有被占用了就会被销毁,null就相当于一个对象的空地址,值就是固定的,占用空间是固定的,这可能就是将错就错的原因,没有用的全局对象不手动销毁,浏览器在不能检测这个变量何时不再使用,就不会销毁,会造成内存泄漏。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Vue项目如何关闭语法检查

    Vue项目如何关闭语法检查

    这篇文章主要介绍了Vue项目如何关闭语法检查问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-04-04
  • Vue中通过minio上传文件的详细步骤

    Vue中通过minio上传文件的详细步骤

    最近项目中使用了minio作为静态资源管理服务,所以简单写一下如何通过minio来上传图片,下面这篇文章主要给大家介绍了关于Vue中通过minio上传文件的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • 基于vue-cli3多页面开发apicloud应用的教程详解

    基于vue-cli3多页面开发apicloud应用的教程详解

    这篇文章主要介绍了基于vue-cli3多页面开发apicloud应用,本文采用vue-cli+APIcloud的方式写解决以上痛点,开发灵活,并且打包之后体积更小速度更快,需要的朋友可以参考下
    2019-06-06
  • vue音乐播放器插件vue-aplayer的配置及其使用实例详解

    vue音乐播放器插件vue-aplayer的配置及其使用实例详解

    本篇文章主要介绍了vue音乐播放器插件vue-aplayer的配置及其使用实例详解,具有一定的参考价值,有兴趣的可以了解一下
    2017-07-07
  • vue中简单弹框dialog的实现方法

    vue中简单弹框dialog的实现方法

    下面小编就为大家分享一篇vue中简单弹框dialog的实现方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-02-02
  • 使用reactive导致数据失去响应式的原因和解决方案

    使用reactive导致数据失去响应式的原因和解决方案

    在 Vue 的响应式系统中,reactive 对象是一个深度代理,它会追踪对象属性的变更,但如果你将整个对象重新赋值,那么 Vue 无法继续追踪新的对象,本文给大家介绍了使用reactive导致数据失去响应式的原因和解决方案,需要的朋友可以参考下
    2024-09-09
  • Vue中使用create-keyframe-animation与动画钩子完成复杂动画

    Vue中使用create-keyframe-animation与动画钩子完成复杂动画

    这篇文章主要介绍了Vue中使用create-keyframe-animation与动画钩子完成复杂动画,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-04-04
  • vue-create创建VUE3项目详细图文教程

    vue-create创建VUE3项目详细图文教程

    create-vue是Vue官方新的脚手架工具,底层切换到了vite(下一代前端工具链),为开发提供极速响应,下面这篇文章主要给大家介绍了关于vue-create创建VUE3项目的相关资料,需要的朋友可以参考下
    2024-03-03
  • vue3中批量全局注册组件实例详解

    vue3中批量全局注册组件实例详解

    在vue中,我们在main.ts引入的全局注册的组件是可以不需要import导入而直接使用的,使用的时候是自己全局注册组件时的名称,而不是组件名,这篇文章主要介绍了vue3中批量全局注册组件,需要的朋友可以参考下
    2023-05-05
  • 关于Vue 监控数组的问题

    关于Vue 监控数组的问题

    这篇文章主要介绍了Vue 监控数组的示例,主要包括Vue 是如何追踪数据发生变化,Vue 如何更新数组以及为什么有些数组的数据变更不能被 Vue 监测到,对vue监控数组知识是面试比较常见的问题,感兴趣的朋友一起看看吧
    2022-05-05

最新评论