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通过ref获取不到$refs问题

    Vue通过ref获取不到$refs问题

    这篇文章主要介绍了Vue通过ref获取不到$refs问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • vue响应式更新机制及不使用框架实现简单的数据双向绑定问题

    vue响应式更新机制及不使用框架实现简单的数据双向绑定问题

    vue是一款具有响应式更新机制的框架,既可以实现单向数据流也可以实现数据的双向绑定。这篇文章主要介绍了vue响应式更新机制及不使用框架实现简单的数据双向绑定问题,需要的朋友可以参考下
    2019-06-06
  • vue使用element实现上传图片和修改图片功能

    vue使用element实现上传图片和修改图片功能

    前几天做到一个关于图片上传功能,下面这篇文章主要给大家介绍了关于vue使用element实现上传图片和修改图片功能的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • vue3使用viewer的详细用法举例

    vue3使用viewer的详细用法举例

    viewer.js用于图片浏览的Vue组件,支持旋转、缩放、翻转等操作,这篇文章主要给大家介绍了关于vue3使用viewer的详细用法,文中通过代码介绍是非常详细,需要的朋友可以参考下
    2023-12-12
  • Vue Render函数原理及代码实例解析

    Vue Render函数原理及代码实例解析

    这篇文章主要介绍了Vue Render函数原理及代码实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • vue-cli-service不是内部或外部命令,也不是可运行的程序或批处理文件问题

    vue-cli-service不是内部或外部命令,也不是可运行的程序或批处理文件问题

    在Vue项目构建过程中,如果遇到无法识别'vue-cli-service'命令的错误提示,通常是因为没有全局安装vue-cli,解决这个问题的步骤主要包括:首先检查Vue版本,如果未安装则先安装Vue;其次全局安装vue-cli;若在安装过程中遇到cnpm命令找不到的情况
    2024-10-10
  • Vue3学习之语法糖、箭头函数、函数声明详解

    Vue3学习之语法糖、箭头函数、函数声明详解

    在Vue3中箭头函数被广泛支持,尤其是在组合式API的上下文中,这篇文章主要给大家介绍了关于Vue3学习之语法糖、箭头函数、函数声明的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-08-08
  • Vue Cli3 打包配置并自动忽略console.log语句的方法

    Vue Cli3 打包配置并自动忽略console.log语句的方法

    这篇文章主要介绍了Vue Cli3 打包配置并自动忽略console.log语句的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04
  • 解决vue ui报错Couldn‘t parse bundle asset“C:\Users\Administrator\vue_project1\dist\js\about.js“. Analyzer

    解决vue ui报错Couldn‘t parse bundle asset“C:

    这篇文章主要介绍了解决vue ui报错Couldn‘t parse bundle asset“C:\Users\Administrator\vue_project1\dist\js\about.js“. Analyzer问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-04-04
  • 详解vue2.0 不同屏幕适配及px与rem转换问题

    详解vue2.0 不同屏幕适配及px与rem转换问题

    这篇文章主要介绍了详解vue2.0 不同屏幕适配及px与rem转换问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-02-02

最新评论