热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

消失的属性

本博客同步自我的Github博客最近在开发组件的过程中,需要随时监控整个组件对象的构建,包括对象上的属性方法的变更,以及原型链的变化。本来,在测试代码中加一个console.log

本博客同步自我的Github博客

最近在开发组件的过程中,需要随时监控整个组件对象的构建,包括对象上的属性方法的变更,以及原型链的变化。本来,在测试代码中加一个console.log

var d = new dialog({
...
});
console.log('final object', d);
d.show();

就可以观察最终生成的组件对象是否符合我的预期,也没出过什么问题,也没理由会出现什么问题,直到调试过程中出现了这样的情况:

组件的配置需要将用户传入的配置属性和默认属性进行合并,然后需要对组件对象中的一个属性布尔值进行判断后改写组件的另一个属性:

this.maskOpacity = this.modal ? this.maskOpacity : 0;

第一眼看上去代码似乎没有问题(实际上有问题),但是运行时和预期行为不一致,this.modal的判定始终为false。那么我就很顺手地打上一句console.log(this)来检查对象的属性,当调整传入的配置对象时,生成对象上的this.modal属性应该会随之变化,检查控制台输出结果,this.modal的值确实是会根据参数不同而变化的。这就奇怪了,试着打断点调试,结果就不一样了,this.modal的值在执行判断时显示为undefined。同样的事情在Chrome和FF中都发生了。

这个modal属性神秘消失了。

问题一分为二,一个是代码本身的逻辑问题,经过进一步调试,在执行到这句判断的时候,配置对象中的modal属性值还未写入this,所以this.modal值为undefined的现象是正常的,通过修改this.modalopt.modal比较轻易就解决了。第二个问题却是在调试过程中遇到的,console.log出的this为何能查找到本不应存在的modal属性,导致误导了我的思路。借助于万能的StackOverflow,最后总算是找到了原因。

这段组件的代码逻辑是比较复杂的,其中的this.modal属性,在上文执行判断的语句处,确实应该undefined,但是在后面的代码中,有这样一段赋值:

this.modal = opt.modal = true;

这段赋值直接改写了this.modal,可为何后文的赋值会影响到前文的输出呢?其中的原因在于,当console.log(this)输出时,this对象在控制台中的显示为折叠状态,如图:
《消失的属性》
为了查看对象中具体的属性信息,就必须用鼠标点一下展开,这个时候,JS早就执行完毕了,this.modal的值也已改写,在展开this对象的时刻,this中的属性显示结果实际上是this对象的最终形态,那么这种输出上的“延迟”是延迟到所有JS执行结束还是仅局限于console语句所在函数作用域内呢?我们可以写段代码验证一下:

var foo = {};
function addProperty() {
foo.test1 = 'test1';
foo.test2 = 'test2';
foo.test3 = 'test3';
foo.test4 = 'test4';
foo.test5 = 'test5';
foo.test6 = 'test6';
foo.test7 = 'test7';
foo.test8 = 'test8';
foo.test9 = 'test9';
console.log(foo);
foo.bar = 'bar';
}
addProperty();
foo.baz = 'baz';
foo = null;
console.log(foo);

代码写得很挫,纯粹是为了测试而写了。在这里我还在最后加了一个对null的指向来销毁对象(严格来说还应该delete掉对象的所有属性,这里省略),控制台中的输出如下:
《消失的属性》
可见,控制台中输出的“延迟范围”是整个脚本代码的范围,不局限于某个函数作用域,同时还不受赋值为null的影响,当然,在foo = null;之后的console的输出就确实为null了。

同时,触发这种“延迟”现象还有一个必要条件,那就是输出对象的属性要足够多,使得控制台会先将对象内容折叠起来,给用户点击展开的机会,如果属性过少,两行就显示完了,也就看不到这个bug了。

在各种条件的巧合作用下发现了这样一个现象,在今后的开发过程中要加以注意,不要受到误导,甚至于利用这种特性为开发提供便捷。


推荐阅读
  • 本文讨论了编写可保护的代码的重要性,包括提高代码的可读性、可调试性和直观性。同时介绍了优化代码的方法,如代码格式化、解释函数和提炼函数等。还提到了一些常见的坏代码味道,如不规范的命名、重复代码、过长的函数和参数列表等。最后,介绍了如何处理数据泥团和进行函数重构,以提高代码质量和可维护性。 ... [详细]
  • 本文介绍了在wepy中运用小顺序页面受权的计划,包含了用户点击作废后的从新受权计划。 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 解决Cydia数据库错误:could not open file /var/lib/dpkg/status 的方法
    本文介绍了解决iOS系统中Cydia数据库错误的方法。通过使用苹果电脑上的Impactor工具和NewTerm软件,以及ifunbox工具和终端命令,可以解决该问题。具体步骤包括下载所需工具、连接手机到电脑、安装NewTerm、下载ifunbox并注册Dropbox账号、下载并解压lib.zip文件、将lib文件夹拖入Books文件夹中,并将lib文件夹拷贝到/var/目录下。以上方法适用于已经越狱且出现Cydia数据库错误的iPhone手机。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • 本文介绍了获取关联数组键的列表的方法,即使用Object.keys()函数。同时还提到了该方法在不同浏览器的支持情况,并附上了一个代码片段供读者参考。 ... [详细]
  • 本文记录了在vue cli 3.x中移除console的一些采坑经验,通过使用uglifyjs-webpack-plugin插件,在vue.config.js中进行相关配置,包括设置minimizer、UglifyJsPlugin和compress等参数,最终成功移除了console。同时,还包括了一些可能出现的报错情况和解决方法。 ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
author-avatar
黄宗翰琼琦莉雯
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有