我看过以两种不同方式定义的对象,其功能相似,但当然是根本不同的。你可以这样做:
var myobject = {property: 'hello',
act: function() {
this.property += ' world';
}};
并且像这样:
function myobject() {
this.property = 'hello';
this.act = function() {
this.property += 'world';
}
}
第二种方法可以创建像这样的对象
var newobj = new myobject();
但是你可以通过使对象成为函数的返回值来使用第一种表示法做类似的事情。 new关键字的优点是能够传递可用于初始化对象属性的参数,但您可以轻松地将init函数添加到第一种对象。
只是想知道除了这两个差异之外,是否存在一个根本区别,使得一种方法肯定比另一种方法更好。
答案 0 :(得分:2)
第二个更好,因为你可以重复使用它。另外,构造对象的constructor
属性在每种情况下都是不同的。
除此之外,第二种方法通过在每次调用构造函数时为act
属性分配一个新函数来浪费空间。 (请注意,第一种方法也以相同的方式浪费空间。)改为使用原型:
function MyConstructor () {
this.property = 'hello';
}
MyConstructor.prototype = {
act: function () {
this.property += 'world';
}
};
MyConstructor.prototype.constructor = MyConstructor;
var obj = new MyConstructor ();
答案 1 :(得分:0)
var f = function () {};
function g () {}
if (typeof(f) === typeof(g)) {
alert(typeof(f) + "\n" + f + "\n" + g);
}
类型相同,变量f具有分配给它的匿名函数。由于f是一个以函数作为其值的命名变量,因此它是一个非匿名函数。 JavaScript是向下继承的lambda语言,允许意外创建全局变量。对于在方差命名空间范围内使用闭包的复杂继承实例,您必须确定定义变量的位置以防止冲突,尤其是考虑重用。第一个约定强制严格意识变量声明,因为必须先声明该函数才能执行它。第二种约定不提供这样的意识,这对于实例化和调用作为先前描述的复杂逻辑中的闭包可能是有问题的。幸运的是,JSLint足够聪明,在声明它之前使用函数时会抛出错误。由于这两个公约的表述形式相同,我建议只使用一个不容易被有缺陷和草率编程滥用的公约。
总结一下,如果g和f都是带有函数作为赋值的命名变量,那么总是使用第一个使用var关键字声明变量的约定以正确的方式执行它。
答案 2 :(得分:0)
javascript:
canDo="b:c=function(){}";
canNot="function a:d(){}";
eval(canDo);
alert(["Can do ",canDo,
".\n\n\nConfirmed result is: \n\n b:c=",
eval("b:c")
].join(""));
alert(
confirm(
"Click OK to confirm this is not valid (can NOT do):\n\n" + canNot) ?
eval(canNot) : "Test will fail if attempted and 'a:d' will not exist."
);
在FireFox中显示:
Can do b:c=function(){}. Confirmed result is: b:c=function () { }
和
Click OK to confirm this is not valid (can NOT do): function a:d(){}
如果选择OK,则会发出运行时错误。