js 记录几个因惯性思维引发的代码BUG,开发思维方式的自我反省
壹 ❀ 引
在写这篇文章之前,对于取什么标题其实让我纠结了好几天,这篇文章中我想说的东西与引用类型数据有关,也与我们的惯性思维有关。本文中展示的几段代码都非常简单,原型都来自于我的日常开发,但让你立刻回答出正确答案可能还需要一点时间,不妨一起来看看吧。
贰 ❀ 测试环节
题目一:
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,开发思维方式的自我反省的更多相关文章
- js记录用户在网站的浏览记录和停留时间
by weber开发者 from http://weber.pub/ 本文地址: http://weber.pub/js记录用户行为浏览记录和停留时间/163.html 问题 公司想统计一个用户从进入 ...
- js记录用户行为浏览记录和停留时间(转)
演示地址:http://weber.pub/demo/160902/test.html 测试源码下载:http://pan.baidu.com/s/1nvPKbSP 密码:r147 解决问题所使用的知 ...
- 打破惯性思维:聊聊一次debug
最近公司的新需求中要增加活动营销,整个组的人都被安排去研究某成熟产品的实现.我也认真地在看webService部分的实现,发现了一个诡异的10614端口的请求. 代码如下图: 这是一段服务端发请求验证 ...
- Cocoa惯性思维调试一例
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 人总有惯性思维,在编程调试里也不例外.你总以为错误是显然的那一 ...
- 为什么我没有拔出钥匙 ——开锁引发的程序bug解决方案的思考
http://blog.csdn.net/wojiushiwo987/article/details/8851204为什么我没有拔出钥匙 ——开 ...
- js让菜单栏一直悬浮在顶部,经典代码
js让菜单栏一直悬浮在顶部,经典代码 很简单,你只需要把下面代码放到js中:$(function(){ //获取要定位元素距离浏览器顶部的距离 var na ...
- JS年月日三级联动下拉框日期选择代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- JS获取屏幕,浏览器窗口大小,网页高度宽度(实现代码)_javascript技巧_
JS获取屏幕,浏览器窗口大小,网页高度宽度(实现代码)_javascript技巧_--HTML5中文学习网 http://www.html5cn.com.cn/shili/javascripts/79 ...
- m_Orchestrate learning system---三十五、php数据和js数据的解耦:php数据(php代码)不要放到js代码中
m_Orchestrate learning system---三十五.php数据和js数据的解耦:php数据(php代码)不要放到js代码中 一.总结 一句话总结:也就是以html为中介,用html ...
随机推荐
- SpringBoot项目里,让TKmybatis支持可以手写sql的Mapper.xml文件
SpringBoot项目通常配合TKMybatis或MyBatis-Plus来做数据的持久化. 对于单表的增删改查,TKMybatis优雅简洁,无需像传统mybatis那样在mapper.xml文件里 ...
- 使用 Anydesk 5.1 TCP 通道(端口映射)功能从外网方便访问内网的 web/数据库等资源
Anydesk 5.1 带来一个新的功能:TCP 通道,在家办公时,通过互联网进行远程桌面连接到公司电脑,可以将家用电脑的某个端口,映射到公司网络的某个电脑( IP + 端口),不局限于被远程桌面连接 ...
- Abp zero 登录 添加腾讯云验证码
腾讯云验证码是为网页.App.小程序开发者提供的安全验证服务,基于腾讯多年的大数据积累和人工智能决策引擎,构建智能分级验证模型,最大程度保护业务安全的同时,提供更精细化的用户体验. 腾讯云--> ...
- [20191125]探究等待事件的本源.txt
[20191125]探究等待事件的本源.txt --//当工作中遇到oracle的性能问题时,查看awr报表提供很好的解决问题途径.但是有时候很容易想当然.--//比如以前我一看到 log file ...
- 《软件安装》VMware 安装 centos8
上期问题回顾 搞技术的同学应该都听过docker,那么请问docker和虚拟机有什么区别呢? 传统的虚拟机架构是:物理机 -> 宿主机操作系统 -> Hypervisor支持 -> ...
- unittest---unittest中verbosity参数设置
我们在做自动化测试的时候,有时候想要很清楚的看到每条用例执行的详细信息,我们可以通过unittest中verbosity参数进行设置 verbosity参数设置 verbosity表示在只执行用例的过 ...
- C# Winform更换Webbrowse为WebKit
本人第一次发表博文,内容不精也不是很有水平,请大家多多包涵~ 说到Webbrowser,可能大家都用过这个控件,它默认使用的是旧版本IE内核. 这就导致了一些问题,比如JS的加载不正确,这个问题就足够 ...
- Redis学习(一)简介
REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统. Redis是一个开源的使用ANSI C语言编写.遵守B ...
- Python爬虫的概括以及实战
第一章主要讲解爬虫相关的知识如:http.网页.爬虫法律等,让大家对爬虫有了一个比较完善的了解和一些题外的知识点. 今天这篇文章将是我们第二章的第一篇,我们从今天开始就正式进入实战阶段,后面将会有更 ...
- QAnet Encoder
#!/usr/bin/python3# -*- coding: utf-8 -*-'''date: 2019/8/19mail: cally.maxiong@gmail.comblog: http:/ ...