资讯专栏INFORMATION COLUMN

消失的属性

andycall / 2211人阅读

摘要:在这里我还在最后加了一个对的指向来销毁对象严格来说还应该掉对象的所有属性,这里省略,控制台中的输出如下可见,控制台中输出的延迟范围是整个脚本代码的范围,不局限于某个函数作用域,同时还不受赋值为的影响,当然,在之后的的输出就确实为了。

本博客同步自我的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了。

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/87641.html

相关文章

  • react-transition-group动画库Transition组件使用

    摘要:动画库这个库包括个组件,今天做项目刚好用到了组件,记录一下使用过程中的总结,另外两个组件用到了再做介绍。规定完成过渡效果需要多少秒或毫秒。规定速度效果的速度曲线。参考网址官方案例官网动画库的新写法 react-transition-group动画库 这个库包括3个组件:Transition,CSSTransition,TransitonGroup,今天做项目刚好用到了Transitio...

    charles_paul 评论0 收藏0
  • react-transition-group动画库Transition组件使用

    摘要:动画库这个库包括个组件,今天做项目刚好用到了组件,记录一下使用过程中的总结,另外两个组件用到了再做介绍。规定完成过渡效果需要多少秒或毫秒。规定速度效果的速度曲线。参考网址官方案例官网动画库的新写法 react-transition-group动画库 这个库包括3个组件:Transition,CSSTransition,TransitonGroup,今天做项目刚好用到了Transitio...

    gityuan 评论0 收藏0
  • 自己整理css3动画库,附下载链接

    摘要:动画以低速开始,然后加快,在结束前变慢。在函数中自己的值。在所指定的一段时间内,在动画显示之前,应用开始属性值在第一个关键帧中定义。动画调用语法 animation: bounceIn 0.3s ease 0.2s 1 both; 按顺序解释参数: 动画名称 如:bounceIn 一周期所用时间 如:0.3s 速度曲线 如:ease 值 描述 linear 动画从头...

    Darkgel 评论0 收藏0
  • CSS中隐藏元素几种方法

    摘要:使用这种方法来隐藏元素,是否可以触发事件要根据具体的情况来分析。其他的方式只作了解即可,并不推荐使用它们来隐藏元素,它们的真正用途应该不在隐藏元素,而是通过了解这些方法的特点,挖掘出其真正的使用场景 几种方法的简单介绍 display:none 最常用的隐藏元素的方法 .hidden{ display:none } 将元素设置为display:none后,元素在页面上将彻底...

    vvpvvp 评论0 收藏0
  • Snackbar源码分析

    摘要:分别对应于中的几个常量值。源码分析的方法源码分析创建需要使用静态的方法,并且其中的参数是一个查找父布局的起点这里可以看到,的布局是,假如我们需要自定义并且设置字体颜色,大小等属性。表示回调已在队列中。 目录介绍 1.最简单创造方法 1.1 Snackbar作用 1.2 最简单的创建 1.3 Snackbar消失的几种方式 2.源码分析 2.1 Snackbar的make方...

    why_rookie 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<