用例没有将函数声明为另一个自定义函数的原型?

时间:2014-10-31 20:12:56

标签: javascript jquery object prototype

我试图了解在现有自定义对象中声明js函数的正确方法。

E.g。通常我这样做是为了向现有对象添加函数:

function whateverController() {
    this.doSomething = function() {

    }
}

以下列方式做什么有什么好处?

function whateverController() {
    ...some random code
} 

whateverController.prototype.doSomething = function() { 

}

从我读过的内容来看,后一个例子是声明这些函数的最佳方式,以避免每次创建一个新的whateverController对象时都必须重新创建这些函数。

有人可以提供一个好的用例,虽然我的前一个例子更适合吗?如果有的话?任何好的阅读链接也会有所帮助!

后一种方法是否被视为标准?

2 个答案:

答案 0 :(得分:1)

首先,如果您不仅仅是制作单身人士,或者换句话说,除非您创建多个实例课程,例如:

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,他们正在使用原型' s whateverController;他们每次都没有创造新功能!现在,如果你有一个包含十几个函数的类,你可以创建该类的一千个实例,并且你仍然只在内存中拥有那些原始的十几个函数。效率更高。

现在,实例,您可能希望使用第一个版本而不是原型版本。当你想要这样做的简短版本非常简单:任何时候你绝对需要一个对象拥有自己特定版本的函数。一般来说,你不会碰到这个,但如果你开始玩#34;私人" JavaScript中的变量,你会发现你很快就会开始需要它们。

然而,所有这一切,请记住,只有在计划制作一个对象的多个实例时,这才真正重要。如果只有一个whateverController,而且只有一个,那么您可以选择更适合您的版本。毕竟,如果您没有创建该类的新实例,那么您也不会创建该函数的新实例。

哦,在我忘记之前还有一个想法:人们普遍认为班级建设者以大写字母开头。换句话说,如果不打算将WhateverController用作单例,并且想要使用它来创建类的实例,则应该将其命名为{{1}}。

答案 1 :(得分:1)

有用的一件事是模拟私人方法和成员

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.
}

这样做的缺点是必须在构造函数内声明私有函数和特权函数。这意味着每次运行构造函数时都会重新创建它们,这对性能不利。但从好的方面来说,他们可以利用这个技巧创建伪私有内容,原型上宣布的内容无法做到。

底线:尽可能将功能放在原型上,但有时候有充分的理由将它们引入构造函数。这不是你应该一直做的事情。