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();

このようにして、の各インスタンスはの同じインスタンスにアクセスできFooます。 ウィットに:への完全なアクセス権がありますが、コンストラクター関数内へのアクセス権はまったくありません:.bar
.barthisvariables

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)を返す関数を定義できます。.bar

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と呼ばれるものを介して、特定のオブジェクトを返した関数内の「プライベート」変数にアクセスできます。 それぞれが引き続きアクセスできます。また、関数を呼び出すと、のように常に参照されます(私の例では)。
.barthisthismyObj.bar();myObjpublic_interfaceFoo

この形式の欠点は、これらのオブジェクトを数百万個作成する場合、それも数百万のコピーであり.bar、メモリに食い込むことです。

コンストラクター関数の内部でこれを行うこともできます。コンストラクターのthis.bar = function () {};内部で設定します。ここでも、コンストラクター内のプライベート変数へのクロージャアクセスがメリットになり、メモリ要件が増加します。

したがって、最初の質問は次のとおりです。オブジェクト自体(または
を介して)からアクセスできない「プライベート」データの読み取り/変更にメソッドがアクセスできることを期待していますか? thismyObj.X

2番目の質問は次のとおりです。共有するのではなく、それぞれに独自の機能を与える場合、メモリが大きな懸念事項になるように、これらのオブジェクトを十分に作成していますか?

たとえば、.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

バーを関数にしてメソッドにすることができます。

Foo.bar = function(passvariable){  };

プロパティとして、文字列、データ型、またはブール値が割り当てられるだけです。

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