违反“Don’t Modify Objects You Don’t Own”原则对SharePoint页面带来的影响
最近看了一本相当不错的JavaScript书,《Maintainable JavaScript》(中文版叫做《编写可维护的JavaScript》),“Don’t Modify Objects You Don’t Own”是这本书第11章的标题,它的意思是,不要去修改不属于你的对象。由于JavaScript动态语言的特性,理论上,我们可以随意的修改任何JavaScript对象(不是说修改对象某个field的值),比如为它们添加一个方法,或是修改原来某个方法的实现。但是从可维护的角度出发,我们不应该在自己的模块中,去随意修改不是由我们自己“管理”的对象,因为我们永远不知道自己的修改,会产生什么额外的影响,带来一个什么样的结果。
这个原则和SharePoint有什么关系呢?嗯,以前我就曾经遇到过一个非常奇怪,曾经花费了我很多时间去debug的一个SharePoint页面错误,而这个错误的起始由来,就是因为在我们的代码中,违反了这个“Don’t Modify Objects You Don’t Own”原则。
首先介绍一下这个页面错误。这个错误非常容易发现,当用户打开一个Web部件页,然后进入到页面编辑状态,然后点击“添加Web部件”按钮。如果页面工作正常,这时页面上方应该会出现Web部件类别和Web部件的列表,让用户选择要添加的Web部件。但是奇怪的是,用户点击“添加Web部件”按钮后,什么也没有发生…
如果使用浏览器自带的开发工具查看console输出,你就会发现一个Type mismatch的脚本错误,而它的来源,尽然来自SharePoint自带的wpadder.debug.js文件。
如果你是第一次遇到这个问题,那么我相信你需要花费大量的时间来调试并找出问题的所在。实际上,引发这个问题的原因,是在我们的某一个自定义JavaScript代码文件中,有如下的一段代码:
这段代码的作用很简单,它为Array对象的原型添加了一个indexOf()方法,这样,在所有的数组对象上,就可以使用indexOf()方法,来确认某个元素的位置。很常见的JavaScript技巧。
“等等,”你可能会说,“实际上,在为一个内置对象的原型添加某个方法之前,最好检查一下这个方法是不是已经被定义过了!”我明白你的意思,你说得很对,(实际上,更新版本的JavaScript里面确实已经在Array的原型上定义了原生的indexOf()方法,但并非所有浏览器都支持)在这里,代码应该这样写:
但很不幸,即使将代码改成这样,那个SharePoint页面错误仍然存在。实际上,只要我们的自定义代码向Array对象的原型添加任何一个方法,比如Array.prototype.indexOf2,那个该死的“Type Mismatch”错误就会出现。要解决这个问题,只需要将所有添加给Array原型的方法移除,就可以了。
你瞧,我们总会遇到一些非常奇怪的问题,而解决它们总会让我们又学到一些新知识。:)