今天下午的时候,同事说发现了一个问题.Ext4作好页面,从新单击菜单动态加载一次,树就消失了. 因而,我帮忙看了一下,一开始没认为是什么大问题.可是越调发现越不对.到快下班的时候,没有什么思路.因而再也不随便看了.好好Debug一下Ext源代码来找问题.到晚上七点半.终于问题搞定了.此次Debug的过程过后想一想真是过瘾.由于不只仅是解决了一个bug.javascript
最重要的是对javascript更进一步有所了解了.java
晚上回家,总以为得记下来,不是记录技术方面的收获,由于知识点变来变去就那么点东西.都是之前就知道的东西,只不过变了一个样子就不会了.我想写写此次调试过程当中的本身的一些猜想还有过后对于程序员的见解.程序员
首先描述一下问题.app
Ext实现简单的动态加载菜单.函数
点击菜单,在TabPanel上加载一个Tab窗体,窗体里面有一个tree控件.this
第一次加载没问题,可是再点击一次的话prototype
对,树就神奇的消失了.debug
代码的话:设计
<!-- lang: js --> //首先是动态加载菜单的代码段 listeners: { itemclick: function (_this, record, item, index, e, eOpts) { if (record.data.leaf) { var MainContiner = Ext.getCmp("MainContiner"); var action = Ext.create(record.raw.action.package, record.raw.action); if (!MainContiner.child(action) || record.raw.action.package == "app.actionPanel.ActionPanel") { MainContiner.add(action); } MainContiner.setActiveTab(action); } } } <!-- lang: js --> //而后是窗体的定义片断的构造函数 constructor: function () { var marktypeTree = Ext.create("app.mark.markTree",{ callback:function(data){ if (data != null) { Ext.getCmp("MainContiner").child("#staffTypeID").child("#panelGridId").treeNode.push(data) Ext.getCmp("MainContiner").child("#staffTypeID").child("#panelGridId").child("#markTypeGrid").store.reload({ params: { _id: data } }) } } }); this.items[0].items.push(marktypeTree); this.callParent(arguments); var a=0; },
第一眼我看到这个问题,先怀疑的是树控件被释放掉了.或者树控件被重写了.可是检查了一遍代码,发现没有这个问题.而后debug看两次单击,窗体到底有什么变化.发现点击两次,panel下面会加入两颗树控件.调试
并且单击次数越多,加入的数量越多.立马就不明白了.按理说第二次单击窗体判断同一个窗体后,不会再加入到tab中.可是树怎么就进去了呢.
而后调试了很长时间,忽然有了一个想法...因而写了一个小例子.........
<!-- lang: js --> function A(){ } function B(){ this.b=1; this.arr=[]; this.obj={}; } A.prototype = new B(); var a = new A(); a.b//这个变量是能够经过圆形查找查到的. a.c=1; a.c//这个c变量在a对象下面, a.arr.push(1);//这个地方就有意思了. //a.arr 会引用到原型里面.push一下后.变量就被增长到 原型对象里面了. //对了.这个地方就是js里面的引用. //对象也符合这个引用. //换句话说 var a2 = new A(); a2.arr.length;//这里length是1.由于原型域是共享的域.
这里反思一下.一直以来,把javascript当作面向对象去学的话.原型会类比继承.可是javascript毕竟不是面向对象的.因此形成这个问题给疏忽了.若是从原型角度来考虑.这就是基本知识点.
问题改过来了.我想到了不少别的问题.
首先对于javascript.再强调一次.把js当作面向对象语言去学是种耍流氓的行为.迟早碰壁.javascript是原型函数式语言. 我能够操做原型域实现面向对象实现不了有意思的功能.若是是面向对象的思惟方式,上面的问题就是Bug.可是这不是.这是一个颇有趣的探索.
其次,关于如何解决bug的问题.感受跳错须要一种回归原点的能力.就是可以把目前的问题回退到问题最初的能力. 不少人调试程序.编译器报错了,就粘贴出来错误百度.而后顺着日后找错.找不到就说这问题无法解决.或者就算找到了.大多经过增长代码的方式去调试.各类条件一限定.不出错了.可是你问为何出错啊?xx的问题....基本都是很表面的答案.
我以为写代码,应该能站到设计者的角度去写.你用Ext.就得站到Ext设计者角度去写代码.理解Ext代码运行机制.一样的bug.有太多的方式能够解决.可是从Ext的运行机制上去考虑解决的方法就没有那么多了.
如何回归代码设计的原点,经过非干预的手段来解决问题.我以为这种理解能力.是一个程序员成长到必定程度会遇到的新的瓶颈.