86

假设我有一个Foo对象

如何通过添加bar()方法来扩展此对象并确保将来的实例Foo具有此方法?

4

4 回答 4

98

您需要将其添加到 Foo 的原型中:

function Foo(){}
Foo.prototype.bar = function(){}
var x = new Foo()
x.bar()
于 2012-11-23T00:46:41.113 回答
69

这一切都取决于您如何创建Foo,以及您打算如何使用.bar().

首先,您是否为您的对象使用了构造函数?

var myFoo = new Foo();

如果是这样,那么您可以使用 扩展Foo函数的prototype属性.bar,如下所示:

function Foo () { /*...*/ }
Foo.prototype.bar = function () { /*...*/ };

var myFoo = new Foo();
myFoo.bar();

以这种方式,Foonow 的每个实例都可以访问 的SAME实例.bar
也就是说:.bar将可以完全访问this,但在构造函数中绝对无法访问variables

function Foo () { var secret = 38; this.name = "Bob"; }
Foo.prototype.bar = function () { console.log(secret); };
Foo.prototype.otherFunc = function () { console.log(this.name); };

var myFoo = new Foo();
myFoo.otherFunc(); // "Bob";
myFoo.bar(); // error -- `secret` is undefined...
             // ...or a value of `secret` in a higher/global scope

以另一种方式,您可以定义一个函数来返回任何对象(不是this),并将.barcreated 作为该对象的属性:

function giveMeObj () {
    var private = 42,
        privateBar = function () { console.log(private); },
        public_interface = {
            bar : privateBar
        };

    return public_interface;
}

var myObj = giveMeObj();
myObj.bar(); // 42

以这种方式,您有一个创建新对象的函数。
这些对象中的每一个都有.bar为它们创建的函数。
每个.bar函数都可以通过所谓的闭包访问函数中返回其特定对象的“私有”变量。
每个.bar人仍然可以访问this,因为this当您调用函数时,likemyObj.bar();将始终引用myObjpublic_interface在我的示例中Foo)。

这种格式的缺点是,如果你要创建数百万个这样的对象,那也是数百万个 的副本.bar,这会占用内存。

您也可以在构造函数内部执行此操作,在构造函数this.bar = function () {};内部进行设置——同样,优点是对构造函数中的私有变量的闭包访问,缺点是增加内存需求。

所以第一个问题是:
您是否希望您的方法能够读取/修改无法通过对象本身(通过thismyObj.X)访问的“私有”数据?

第二个问题是:如果你给它们每个人自己的个人功能,而不是给他们一个分享,你是否制造了足够多的这些物品,以至于记忆将成为一个大问题?

例如,如果您.draw在高端 3D 游戏中为每个三角形和每个纹理赋予其自己的功能,那可能有点矫枉过正,而且在如此精致的系统中可能会影响帧率……

但是,如果您希望每页创建 5 个滚动条,并且您希望每个滚动条都能够设置其位置并跟踪它是否被拖动,而无需让所有其他应用程序都有权读取/设置这些相同的东西,那么假设它可能已经有 10,000 行(或更多)长,那么真的没有理由害怕 5 个额外的函数会杀死你的应用程序。

于 2012-11-23T01:13:12.480 回答
13

有很多方法可以在 JavaScript 中创建像这样的可重用对象。Mozilla 在这里有一个很好的介绍:

以下内容适用于您的示例:

function Foo(){
    this.bar = function (){
        alert("Hello World!");
    }
}

myFoo = new Foo();
myFoo.bar(); // Hello World​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
于 2012-11-23T00:45:52.963 回答
11

您可以使 bar 成为一种功能,使其成为一种方法。

Foo.bar = function(passvariable){  };

作为一个属性,它只会被分配一个字符串、数据类型或布尔值

Foo.bar = "a place";
于 2012-11-23T01:01:10.513 回答