在JavaScript中,为什么要将属性直接附加到构造函数?
var Human = function() {};
Human.specie = "Homo Sapience";
在查看CoffeeScript的__extend
辅助函数后,我有了这个问题,其中包含以下几行:
for ( var key in parent ) {
if ( __hasProp.call( parent, key ) ) child[key] = parent[key];
}
直接从构造函数对象将属性/方法复制到子类对象。但为什么有人这样做呢?
谢谢!
答案 0 :(得分:2)
(编辑:)在原始形式中,问题是关于将属性附加到类而不是将它们附加到原型,这就是我正在回复的内容。)
这实际上更多的是约定而不是其他任何事情。如果你写
Human::specie = "Homo sapiens"
(其中Human::specie
是Human.prototype.specie
的CoffeeScript简写)然后声明jane = new Human
,然后jane.specie
将"Homo sapiens"
(除非您专门设置jane.specie
到其他东西)。在这种情况下,这听起来是可取的。
但在其他情况下,在大量原型中共享属性会使您的代码更难理解。假设您有一个Logger
类,其中包含config
个对象。如果您将该对象附加到原型,那么您可以编写如下代码:
log = new Logger
log.config.destination = './foo'
这会将所有 Logger
个实例的目标更改为'./foo'
,因为只有一个config
个对象。如果您希望config
应用于所有Logger
个实例,那么您应该将其附加到正确的类中,从上面的代码中消除歧义:
log = new Logger
Logger.config.destination = './foo'
答案 1 :(得分:1)
在游戏中说你有一个叫做世界的物体。然而,游戏中只会有一个世界。理论上这就是你这样做的原因。
答案 2 :(得分:0)
简而言之,发布的问题的答案是名称间距。某些值可能有意义在您的程序中共享,并且在语义上与某些类有关。这些函数和值可以只放在一些变量中,但是将它们附加到构造函数是可行的,以便命名它们。
最好的例子是JavaScript Math
类(对于纯粹主义者,我知道它不是真正的类,它是一个对象):
// There are constants
Math.E
Math.PI
Math.SQRT2
// And there are also methods
Math.ceil
Math.cos
Math.sin
因此,方法和值(保存在常量中)总是相同的,并且它们不依赖于它们被调用的实例,并且将它们放在实例上是没有意义的。