【发布时间】:2013-02-03 15:54:06
【问题描述】:
前几段描述了我想要实现的目标,实际问题在最后。谢谢
以前,我只是使用new 关键字来创建对象,并使用原型来分配方法和处理继承。然而,最近(部分受到 CoffeeScript 生成的 JS 的启发)我决定使用一个看起来像这样的对象创建函数:
var Test = function(a) {
function Test(a) {
this.a = a;
}
var numCalls = 0;
Test.prototype.output = function() {
alert('I was initialized with ' + this.a);
numCalls++;
};
Test.prototype.called = function() {
alert('You called the output ' + numCalls + ' times');
};
return new Test(a);
};
然后我会像这样创建一个新对象:
var obj = Test('string');
与对每个实例都使用new 的典型方法相比,这种方法有几个优点。首先,我不太可能忘记使用new 这个词(我知道还有其他避免new 的方法,但据我所知,它们与我在下面描述的问题有类似的问题),其次,我可以很容易地看到构造函数在现在属于类的任何函数中看到的“私有”变量。不过,我在测试时确实遇到了警告。 instanceof 不再起作用,因为它看不到内部作用域对象 Test。为了解决这个问题,我尝试使用构造函数属性:
var a = Test('one');
var b = Test('two');
a.constructor == b.constructor // false
a.constructor.name == b.constructor.name // true
这就是让我感到困惑的地方。在不使用对象创建函数的情况下创建相同的对象会导致它们的构造函数相等,但在这种情况下它们是不同的。我的猜测是,每次函数运行时都会生成一个全新的对象类型(对象结构相同,但原型的实例不同)。
如果我对问题的理解是正确的,这是否也意味着代码为每个对象实例分配额外的内存给我的 JavaScript 用于应该在实例之间共享的函数,方法是欺骗它为每个实例创建相同的对象原型(违背了使用原型的全部目的)?如果是这样,是否有一种避免这种情况的好方法,同时仍然保持这种模式的好处(能够在内部函数之间共享私有变量并且不必使用 new 关键字)?
如果我误解了这个问题,有人可以告诉我实际发生了什么吗?
【问题讨论】:
-
为什么忘记关键字new?我的意思是,每次创建新对象时,都使用“new”,这非常简单。这个解决方案在许多 OO 语言中存在了几十年,这是一件很棒的事情,因为每个人都可以阅读和理解你的代码。虽然没有人理解 var obj = Test('string'),但您的代码的可读性会降低。但我知道,这是一些 JS 程序员的最终目标。 ;)
-
@Marcus,如前所述,
new关键字并不是这种模式的唯一优势。另外,我不是团队中唯一的程序员。假设每个人都永远记得使用new关键字,同时还用Python 编写后端(它不使用new进行类)是不现实的。在类声明的末尾发现缺少的new比在每次创建实例时要容易得多。 -
啊,我现在明白了:没有编译器告诉程序员他忘记了“new”,所以这就是你不想使用它的原因。
-
据我所知,这是 IE 中的一个问题?!
标签: javascript memory-management