博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个 js 中值传递和引用传递的坑。
阅读量:6717 次
发布时间:2019-06-25

本文共 1569 字,大约阅读时间需要 5 分钟。

今天在调试代码时遇到一个问题,刚开始想不明白,然后分析了一下后,才知道其中的问题,这也是一个基础的问题,(所以基础是很重要的)

代码如下:

var a = 3;a = a * 2;console.log(a); // a = 6var b = 1, c =2, d = 3;var arr1 = [b,c,d];arr1.forEach((item)=>{    item = item * 2;});console.log(arr1); //arr1 = [1,2,3];var arr2 = [{a:1},{a:2},{a:3}];arr2.forEach((item)=>{    item.a = item.a*2;});console.log(arr2); //arr2 = [{a:2},{a:4},{a:6}]

如果你能不假思索的得出上面的答案,我相信你对这方面的知识已经很了解了,所以可以不用继续往下看了,如果你像我今天该开始一样,觉得有点疑惑的话,那么这篇文文章就很适合你。

  1. 首先我们应该知道的是,在 javascript 中,基本数据类型是通过值传递的。

比如:

var a=1,b;    b = a;// 这时 a 和 b 的值都为 1    a = 2;//这时 a 的值 为 2,b 的值还是为 1 ,

图片描述

所以当 b = a, a = 2;a直接赋给b的值 是1,所以 b 就等于 1,而 a 的变化改变不了 b 的值

  1. 在 js 中复杂数据类型是通过 引用传递的

比如:

var v1 = { a:1 };var v2 = v1; //v2 = { a:1 }v1.a = 2;console.log(v2.a); // v2.a = 2;

图片描述

了解了以上的一些基础知识后,就不难理解最开始的代码输出结果了。

1.    var a = 3;    a = a * 2;    console.log(a); // a = 6    2.     var b = 1, c =2, d = 3;    var arr1 = [b,c,d];    arr1.forEach((item)=>{    item = item * 2;    });    console.log(arr1); //arr1 = [1,2,3];    3.     var arr2 = [{a:1},{a:2},{a:3}];    arr2.forEach((item)=>{    item.a = item.a*2;    });    console.log(arr2); //arr2 = [{a:2},{a:4},{a:6}]

第一段代码当然好理解,就是简单的值传递而已,然而第二段代码呢?我刚开始有点困惑的是,既然也是值传递,那为什么它的值没有变化还是原先的值,注意:这里我忽略了重要的一点,所以导致我不明白,那就是在这个 forEach 的遍历中,还存在一个赋值的过程,就是这个过程导致 arr1 的值没有改变,在每次循环中 arr1中的值都会赋给 item, 就是 item = b, item = c,item = d,所以后面对item 的改变就与 b,v,d 没有关系了。

所以那么 第三段也就很好理解了,他也与第二段代码一样,每次回存在一个赋值,但是注意的是 arr2 中存储的是对象,就是 item = { a:1 } ...,这样 item 仍然指向 arr2 中对象,所以这时对 item 的修改就可以通过 arr2 来反应出来。

虽然这只是自己的粗心造成的,但仍然是自己的基础不扎实而导致的,所以想要成为好的程序员,基础是非常重要的。希望大家都能注重基础的知识,为自己学习高级东西而打下坚实的基础。

转载地址:http://hvumo.baihongyu.com/

你可能感兴趣的文章
C# Lambda表达式Contains方法 like
查看>>
第三章--进程
查看>>
Docker部署CouchDB
查看>>
关于namespace的一点点心得体会(2017年8月3日14:55:37)
查看>>
Android Studio中默认图标的引用
查看>>
keepalived的原理和基本实现
查看>>
Android Activity之间动画完整版详解
查看>>
绕过管理员验证登陆!
查看>>
Android Studio 初体验
查看>>
MySQL常用DDL、DML、DCL语言整理(附样例)
查看>>
解决HP6531s随时禁用或启用触摸板的问题
查看>>
ORM数据层框架的设计热点:更新指定的列的几种设计方案
查看>>
access数据库注入
查看>>
语言的歧义
查看>>
dede后台空白或者登录以后空白,点注销以后也是空白的解决方式
查看>>
微软虚拟化之一Hyper-V 2.0的安装及基本配置
查看>>
Silverlight实用窍门系列:52.Silverlight中的MVVM框架极速入门(以MVVM Light Toolkit为例)...
查看>>
DNS服务-详解
查看>>
mysqldump结合脚本的备份方案
查看>>
httpd-2.4 基础配置图解及实现
查看>>