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就相当于一个对象的空地址,值就是固定的,占用空间是固定的,这可能就是将错就错的原因,没有用的全局对象不手动销毁,浏览器在不能检测这个变量何时不再使用,就不会销毁,会造成内存泄漏。

总结

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

相关文章

  • vue3使用vue-count-to组件的实现

    vue3使用vue-count-to组件的实现

    这篇文章主要介绍了vue3使用vue-count-to组件的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • Vue.use()在new Vue() 之前使用的原因浅析

    Vue.use()在new Vue() 之前使用的原因浅析

    本文通过实例代码给大家介绍了为什么Vue.use()在new Vue() 之前使用,需要的朋友可以参考下
    2019-08-08
  • 简单理解vue中track-by属性

    简单理解vue中track-by属性

    这篇文章主要帮助大家简单的理解vue中track-by属性,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • 一文详解如何在vue中实现文件预览功能

    一文详解如何在vue中实现文件预览功能

    很多Vue项目中都需要PDF文件预览功能,比如合同ERP,销售CRM,内部文档CMS管理系统,内置PDF文件在线预览功能,下面这篇文章主要给大家介绍了关于如何在vue中实现文件预览功能的相关资料,需要的朋友可以参考下
    2022-10-10
  • 通过vue-cropper选取本地图片自定义裁切图片比例

    通过vue-cropper选取本地图片自定义裁切图片比例

    这篇文章主要介绍了Vue选取本地图片,自定义裁切图片比例 vue-cropper,本文分步骤结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-07-07
  • vue中使用jwt-decode解析token的方法

    vue中使用jwt-decode解析token的方法

    这篇文章主要介绍了vue中使用jwt-decode解析token,文末给大家补充介绍了vue通过jwt-decode解析token获取需要的数据,本文给大家介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • el-table表格动态合并行及合并行列实例详解

    el-table表格动态合并行及合并行列实例详解

    在使用el-table的时候经常会涉及到表格的列合并,包括表格操作列的合并,下面这篇文章主要给大家介绍了关于el-table表格动态合并行及合并行列的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-10-10
  • Vue嵌套iframe时$router.go(-1)后退bug的原因解析

    Vue嵌套iframe时$router.go(-1)后退bug的原因解析

    这篇文章主要介绍了Vue嵌套iframe,$router.go(-1)后退bug的问题原因及解决方法,本文给大家分享问题原因所在及解决方案,需要的朋友可以参考下吧
    2023-09-09
  • VUE引入使用G2图表的实现

    VUE引入使用G2图表的实现

    本文主要介绍了VUE引入使用G2图表的实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • Vue.js 前端路由和异步组件介绍

    Vue.js 前端路由和异步组件介绍

    这篇文章主要介绍了Vue.js 前端路由和异步组件介绍,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09

最新评论