在javascript中,应该尽量避免new 操作符
Javascript 是原型语言,但是他拥有 new 操作符,这使它看上去更像面向对象语言的类别,往往混淆程序员,从而导致一些有问题的编程模式的出现。
其实,在javascript中,你完全没有必要用new Object(),而应该采用对象字面量{}的方式进行声明。类似地,采用数组字面量[]的方式来代替new Array()对数组进行声明。Javascript中的数组内部运作机制不同于java中的数组,采用类似java的语法往往也会使学习javascript的人感到困惑。更进一步来讲,不要用new Number,new String 或者new Boolean进行声明变量,这些形式也会产生不必要的对象容器,请采用他们简单的字面量来代替。
根据以上的推论,对于函数的声明来讲,采用new Function 来创建函数值也是不理智的。而应该采用函数表达式的方式进行声明。例如:
frames[0].onfocus = new Function("document.bgColor='antiquewhite'")
对于以上的声明方式,我们应该这样写:
frames[0].onfocus = function () {document.bgColor = 'antiquewhite';};
两者相比较,后者可以被编译器更早地发现函数体,如果有任何语法错误就会在函数执行前被发现,而前者则是在javascript代码执行的时候才会逐行解析。概括地说,函数表达式的声明是发生在javascript预解析阶段,而采用new Function的方式则发生在javascript执行的过程中。有时候,new Function 的声明方式会使采用它的人不懂得其函数内部代码是如何执行的。
selObj.onchange = new Function("dynamicOptionListObjects["+dol.index+"].change(this)");
无论我们以字符串的形式声明函数体(new Function())还是以字符串表达式来声明函数体(函数表达式),javascript解析器都不会在预解析阶段发现函数体,这在迭代或循环过程中动态传递某些值是比较困难的。但是,如果我们来构造一个函数(例如采用闭包的形式)让其返回值也是一个函数,我们就可以明确地传递我们想要绑定的值。这允许我们用迭代的方式来初始化某个对象的属性集合。
selObj.onchange = function (i) {
return function () {
dynamicOptionListObjects[i].change(this);
};
}(dol.index);
把new 直接放在function的前面也不是一个好主意,这在构造新对象不具有任何优势。
myObj = new function () {
this.type = 'core';
};
更好的方式是采用对象字面量,因为它简短、效率高。
myObj = {
type: 'core'
};
同样地,如果我们构造一个包含绑定到私有变量与函数的方法,最好也要远离new 前缀。
var foo = new function() {
function processMessages(message) {
alert("Message: " + message.content);
}
this.init = function() {
subscribe("/mytopic", this, processMessages);
}
}
因为采用new 来调用函数,对象会一直保持着无用的原型对象,毫无用处地占有内存空间。没有new调用function,我们就不会保留没有用处的原型链对象。所以,我们应该采用()来调用工厂模式下的函数。
var foo = function () {
function processMessages(message) {
alert("Message: " + message.content);
}
return {
init: function () {
subscribe("/mytopic", this, processMessages);
}
};
}();
规则很简单:我们采用new 操作符的唯一情况就是调用自定义对象构造函数来创建对象的时候,这时候,new 是强制采用的。
原文链接:http://yuiblog.com/blog/2006/11/13/javascript-we-hardly-new-ya/
初次翻译文章,语言显得呆板枯燥,不可避免地也会与原作者产生一些理解的差异,如有任何错误或疑问请指出,谢谢。