壹 ❀ 引

在写这篇文章之前,对于取什么标题其实让我纠结了好几天,这篇文章中我想说的东西与引用类型数据有关,也与我们的惯性思维有关。本文中展示的几段代码都非常简单,原型都来自于我的日常开发,但让你立刻回答出正确答案可能还需要一点时间,不妨一起来看看吧。

 贰 ❀ 测试环节

题目一:

let getName = (name) => {
return name;
};
let person = {
name: getName('听风是风')
};
getName('echo');
console.log(person);//?

开发中初始化工作总是必不可少的,初始化数据,变量都是非常常见的操作。现在我需要初始化一个对象,而这个对象的值是一个被调用函数;于是在后面的程序中我需要更新这个对象,顺手再次调用了这个函数,那么请问此时这个对象能被更新吗?

答案是并不会更新,其实仔细想想这怎么可能被会更新呢。但在开发中,因为引用类型数据保存是存放value的指针,这让我有了一种函数被再次调用return的值被刷新,于是person对象也被更新的错觉,听着挺蠢,可是我不严谨的惯性思维却真的写出了这样的代码,并调试了好一会BUG。

题目二:

let arr = [{
id: 1,
name: '听风是风'
}, {
id: 2,
name: '时间跳跃'
}];
arr.forEach((item) => {
item.a === 1 ? item = {id: 3,name: 'echo'} : null;
});
console.log(arr);//?

日常开发中遍历数据的操作简直与我们每天要吃饭一样平常,那么现在我需要将数组中符合条件项的元素直接替换成另一个元素,也就是上述代码,请问执行完毕数组有被成功更改吗?

答案是并没有更改,但惯性思维会让我觉得,此时的item就是数组中的某个对象,我将对象替换数组也会得到替换,这是潜意识的思维方式。

但事实上item并不是数组中的某个元素,而是作为forEach回调函数的一个局部形参临时存储了数组中的某个元素,为了方便理解我们修改代码:

arr.forEach((item,index) => {
item = arr[index];//这一步是隐性的
item.a === 1 ? item = {id: 3,name: 'echo'} : null;
});

上述代码再简化就是下面这段代码:

let a = [1, 2];
let b = a;
b = [1, 2, 3];
console.log(a); //[1,2]

虽然变量b曾与变量a共享过数组[1,2]的地址指针,可是后来变量b变心了,改成保存数组[1,2,3]的指针,所以怎么可能会影响到变量a呢。上述例子也是,item被重新赋值关我数组何事,所以数组肯定不会被改变。

但如果变量b不是做重新赋值,而是单纯的修改,这就会影响到变量a,因为它两其实保存的是同一个数组的指针,像这样:

let a = [1, 2];
let b = a;
b[0] = 2;
console.log(a); //[2,2]

题目三:

function fn(param) {
param = 2;
};
let obj = {
a: {
b: 1
}
};
fn(obj.a.b);
console.log(obj);//?

我有一个对象obj,它的属性层级有点高,在某个场景下我需要将此对象作为参数传入函数fn,达到赋值的操作,那么请问上述代码中的对象obj成功被赋值了吗?

答案是并没有,让我产生可行错觉的原因是因为我觉得obj层级过高,为了统一和简化函数fn的赋值代码,我得清楚知道是给对象的哪一级赋值,于是才诞生了这样的写法。

但只要稍微仔细一想,obj.a.b拿到的是一个具体的value,事实上我们只能给key赋值,哪里有给value赋值value的操作呢。

 叁 ❀ 总

文章到这里,我一共展示了三个我个人觉得有趣也常让人误解的代码问题,这些问题稍加思考就会觉得特别简单,但事实上我将它们整理出来用于测试我的同事,他们居然都会犹豫,而且大部分都回答错误了。

难的不是问题,难的是我们太容易相信自己的潜意识,惯性思维。它应该是这样,它应该会这么运行,但代码一跑总是被BUG打脸,如果代码量大,还得花费较大的时间确认问题出自于哪里,这也是我被折磨后非常想要写一篇文章记录的原因。

在开发中明确一个变量一段执行此时是什么,而不是我觉得它应该是什么,写代码如果靠猜,往往在写完后会付出更多的时间用于调试,因为自己其实是不确定的,一个程序代码量越大,这种不确认感就会越强,反过来想不如确信后写更值得相信的代码要来的省时省力。

这是一篇偏向自我反应的文章,不知道上述问题大家有没有遇见过,那么到这里本文结束。

js 记录几个因惯性思维引发的代码BUG,开发思维方式的自我反省的更多相关文章

  1. js记录用户在网站的浏览记录和停留时间

    by weber开发者 from http://weber.pub/ 本文地址: http://weber.pub/js记录用户行为浏览记录和停留时间/163.html 问题 公司想统计一个用户从进入 ...

  2. js记录用户行为浏览记录和停留时间(转)

    演示地址:http://weber.pub/demo/160902/test.html 测试源码下载:http://pan.baidu.com/s/1nvPKbSP 密码:r147 解决问题所使用的知 ...

  3. 打破惯性思维:聊聊一次debug

    最近公司的新需求中要增加活动营销,整个组的人都被安排去研究某成熟产品的实现.我也认真地在看webService部分的实现,发现了一个诡异的10614端口的请求. 代码如下图: 这是一段服务端发请求验证 ...

  4. Cocoa惯性思维调试一例

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 人总有惯性思维,在编程调试里也不例外.你总以为错误是显然的那一 ...

  5. 为什么我没有拔出钥匙 ——开锁引发的程序bug解决方案的思考

    http://blog.csdn.net/wojiushiwo987/article/details/8851204为什么我没有拔出钥匙                             ——开 ...

  6. js让菜单栏一直悬浮在顶部,经典代码

    js让菜单栏一直悬浮在顶部,经典代码 很简单,你只需要把下面代码放到js中:$(function(){                //获取要定位元素距离浏览器顶部的距离        var na ...

  7. JS年月日三级联动下拉框日期选择代码

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. JS获取屏幕,浏览器窗口大小,网页高度宽度(实现代码)_javascript技巧_

    JS获取屏幕,浏览器窗口大小,网页高度宽度(实现代码)_javascript技巧_--HTML5中文学习网 http://www.html5cn.com.cn/shili/javascripts/79 ...

  9. m_Orchestrate learning system---三十五、php数据和js数据的解耦:php数据(php代码)不要放到js代码中

    m_Orchestrate learning system---三十五.php数据和js数据的解耦:php数据(php代码)不要放到js代码中 一.总结 一句话总结:也就是以html为中介,用html ...

随机推荐

  1. 2019 DevOps 必备面试题——容器化和虚拟化

    原文地址:https://medium.com/edureka/devops-interview-questions-e91a4e6ecbf3 原文作者:Saurabh Kulshrestha 翻译君 ...

  2. Linux中crontab定时任务

    crontab安装(centOS) yum -y install vixie-cron crontab语法(计划任务) crontab [-u user] file crontab [-u user] ...

  3. 012.MongoDB读写分离

    一 读写分离概述 1.1 读写分离描述 从应用程序角度来看,使用Replica Set 和使用单台mongo很像.默认的驱动程序会连接primary节点,并且将所有读写请求都路由到主节点.但也可以通过 ...

  4. 在vue-cli3中使用axios获取本地json

    在vue-cli3中,公共文件夹由static变成了public 先把要访问的json放到public文件夹下 使用axios的get方法获取,不能用post,不然会报404 axios..json` ...

  5. Java之StringBuilder类

    StringBuilder类的由来 由于String类的对象内容不可改变(底层是一个被final修饰的数组),所以每当我们进行字符串拼接时,总是会在内存中创建一个新的对象.如果对字符串进行拼接操作,每 ...

  6. 阿里云搭建wordpress博客教程

    一 :搭建环境 1.安装Apache环境 在线安装Apache yum install httpd 启动Apache服务 service httpd start 设置开机自启动 chkconfig h ...

  7. LeetCode 771: 宝石与石头 Jewels and Stones

    题目: 给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头. S 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石. You're given strings ...

  8. 解决CentOS7 Local time比实际时间相差8小时

    GPS系统中有两种时间区分,UTC就0时区的时间,CST为本地时间,如北京为早上八点(东八区),UTC时间比北京时晚八小时; CST:China Standard Time,UTC+8:00 中国沿海 ...

  9. BeautifulSoup的重要操作

    BeautifulSoup相关概念总结:https://www.cnblogs.com/pythonywy/p/11134481.html css基础以及选择器基础:https://www.cnblo ...

  10. java简单实现用语音读txt文档

    最近比较无聊,随便翻着博客,无意中看到了有的人用VBS读文本内容,也就是读几句中文,emmm,挺有趣的,实现也很简单,都不需要安装什么环境,直接新建txt文件,输入一些简单的vbs读文本的代码,然后将 ...