我正试图找到在现有自定义对象中声明js函数的正确方法。
例如,通常我这样做是为了向现有对象添加函数:
function whateverController() {
this.doSomething = function() {
}
}
按照以下方式做有什么好处?
function whateverController() {
...some random code
}
whateverController.prototype.doSomething = function() {
}
从我读到的内容来看,后一个例子是声明这些函数的最佳方式,以避免每次创建新的whateverController对象时都必须重新创建这些函数。
有人能提供一个好的用例吗?尽管我以前的例子更适合哪里?如果有的话?任何好的阅读链接都会很有帮助!
后一种方法被认为是标准的吗?
它有用的一点是模拟私有方法和成员。
JavaScript没有指定可见性的方法,但有一种方法可以通过使用闭包进行欺骗当你运行一个函数时,它的变量存在于一个闭包中,只要有任何东西引用它,它就会一直存在,但除非你把它们附加到存在于闭包之外的东西上,否则任何东西都看不到它们。。你的代码没有显示它,但你可以做这样的事情:
function whateverController() {
// START OF SCOPE
var privateMember = "secret"; // this acts like a private member.
function privateMethod() {
// This function is private.
// Only other functions declared inside this call can see it.
// But it can see privateMember, and other private stuff, just fine.
}
this.doSomethingPublic = function() {
// This function is public and privileged.
// It can see privateMember and privateMethod, and outside functions can see it.
// This is because you attached it to "this".
}
// END OF SCOPE
}
whateverController.prototype.doSomethingElse = function() {
// This method is public but not privileged.
// It cannot see privateMember or privateMethod,
// because they were declared outside its scope. But it CAN
// see this.doSomethingPublic, because you attached it to this.
}
这样做的缺点是,私有函数和特权函数必须在构造函数内部声明。这意味着每次运行构造函数时都会重新创建它们,这对性能不利。但从好的方面来说,他们可以使用这个技巧来创建伪私有的东西,而在原型上声明的东西是做不到的
底线:最好尽可能将函数放在原型上,但有时有充分的理由将它们拉入构造函数。这不是你应该一直做的事情。
首先,只有当您不只是创建singleton时,这里的差异才真正重要——换句话说,除非您创建了一个类的多个实例,否则所有这些都无关紧要,例如:
var redController = new whateverController();
var blueController = new whateverController();
现在,如果正在创建一个对象的多个实例,那么将尽可能多的实例放在类的原型上是可行的。原因很简单。如果我们这样做:
function whateverController() {
this.doSomething = function() {
// TODO - do stuff
}
}
var redController = new whateverController();
var blueController = new whateverController();
var greenController = new whateverController();
redController.doSomething(); // Works fine!
blueController.doSomething(); // Yup, this too!
greenController.doSomething(); // Looking good!
它会起作用,但要付出代价:每个new whateverController()
都会创建自己的doSomething
。换句话说,您现在有三个完全独立的doSomething
函数浮动。
想象一下,如果这个类有十几个函数,并且您创建了几十个它的实例?它很快就失控了。
这就是原型版本的用武之地。如果我们将代码更改为:
function whateverController() {
// ...some random code
}
whateverController.prototype.doSomething = function() {
// TODO - do stuff
}
var redController = new whateverController();
var blueController = new whateverController();
var greenController = new whateverController();
redController.doSomething(); // Alright!
blueController.doSomething(); // Still good!
greenController.doSomething(); // ...you get the idea ;)
现在,每个控制器都没有自己的doSomething
,而是使用原型的doSomething
;他们并不是每次都创建一个新函数!现在,如果你有一个有十几个函数的类,你可以创建该类的一千个实例,而你在内存中仍然只有最初的十几个函数。效率高得多。
现在,在的实例中,您可能希望使用第一个版本而不是原型版本。当你想这样做的时候,简短的版本非常简单:任何时候,你绝对需要一个对象拥有它自己的特定版本的函数。一般来说,你不会遇到这种情况,但如果你开始在JavaScript中使用"私有"变量,你会发现你很快就开始需要它们。
尽管如此,请记住,只有当您计划创建一个对象的多个实例时,这才真正重要。如果只有一个whateverController
,而且永远只有一个,你可以选择你更喜欢的版本。毕竟,如果不创建类的新实例,那么也不会创建函数的新实例。
哦,在我忘记之前还有一个想法:类构造函数以大写字母开头是公认的。换句话说,如果不打算将whateverController
用作单例,并且希望使用它来创建类的实例,那么可能应该将其命名为WhateverController
。