3

ユーザーが提供する仕様に基づいてオブジェクトを構築するための小さなライブラリに取り組んでいます。継承やその他の多くのクラス機能を持つことができます。

ただし、関数をクラスとして使用していないため、私のアプローチは通常のアプローチとは異なります。

これは作成されたオブジェクトの例です:

var objectTest = {
    someVar: 5,
    someMethod: function () {...}
};

これが本当に欲しいものです。ただし、他のすべてのクラスの実装には、異なるアプローチがあります。それらはすべてクラスとして関数を持つことになります。


編集:(明確にするために)

通常のアプローチ:

  • 関数をクラスとして使用します。
  • 「new className()」を使用して新しい関数を作成し、それらをオブジェクトとして使用します。

私のアプローチ:

  • ライブラリを使用して、基本値/メソッドと、それらが相互に継承される方法を指定します。
  • 「myLib.create('className')」を使用して新しいオブジェクトを作成し、それらをオブジェクトとして使用します。

その背後にある理由は理解できます。おそらく、プロトタイプを使用する方がより論理的です。

しかし、私のアプローチには目に見えない欠点があるのか​​ 、それとも私がやっていることは何か他のものと呼ばれているのではないかと思っています.

助けや批判は大歓迎です。

4

3 に答える 3

1

あなたのアプローチには、プロトタイプの使用と比較してこれらの欠点があります。

  • オブジェクトの各値に対して新しい関数を定義します。これにより、オブジェクトの作成が遅くなり、無駄なメモリが必要になります
  • プロトタイプのように継承を定義することはできません

したがって、実際にはクラスを定義しているわけではありません。クラスは、同じ動作を共有するインスタンスが存在できる場合にのみ意味がありますが、オブジェクトのみです。

一方、「インスタンス」が 1 つだけ必要な場合は、まったく問題ありません。

MDN は、プロトタイプの継承に関する優れたガイドを提案しています。


インスタンスごとに新しい関数を定義すると言う理由:

var obj1 = {
    someVar: 5,
    someMethod: function () {console.log(this.someVar)}
};
var obj2 = {
    someVar: 5,
    someMethod: function () {console.log(this.someVar)}
};
console.log(obj1.someMethod==obj2.someMethod); // logs false

プロトタイプの使用は機能を複製しませんが:

function MyClass(avar){
    this.someVar = avar;
}
MyClass.prototype.someMethod = function(){
    console.log(this.someVar);
};
var obj1 = new MyClass();
var obj2 = new MyClass();
console.log(obj1.someMethod==obj2.someMethod); // logs true 
于 2012-12-07T14:58:06.833 に答える
0

クラスの概念に関数が使用されているのは、スコープのためです。JavaScript は関数スコープであるため、コンテインメント (つまり、名前空間や型名の衝突がないなど) のために、関数はスコープをキャプチャする方法です。JavaScript でのオブジェクト定義では、基本的にすべてがパブリック コレクションの一部です。それが必要な動作であれば、アプローチは問題ありません。変数やメソッドを保護して非公開にしたり、競合を回避したり拡張性を確保したりするためにサービスを一意の名前空間にスコープする必要がある場合は、関数やクロージャについて学び、それらをクラスのサービスとして実装する必要があります。

これをモジュールレベルにスコープすることに関する素晴らしい投稿は次のとおりです 。 -module-pattern.aspx

プロトタイプ レベル: http://weblogs.asp.net/dwahlin/archive/2011/08/03/techniques-strategies-and-patterns-for-structuring-javascript-code-revealing-prototype-pattern.aspx

于 2012-12-07T15:05:41.280 に答える
0

JavaScript では、関数をオブジェクトのコンストラクターとして使用することが許可されています。

これがある場合:

function Foo() {
    this.bar = "bar";
}

var b = new Foo();
alert(b.bar); "bar"

Foo関数をコンストラクターとして使用して、新しいオブジェクトを作成しました。オブジェクトの作成にいくつかのロジックを入れるのに便利です。


また、継承された値を設定することもできます。.prototypeのオブジェクトにプロパティを追加すると、Foo作成された新しいオブジェクトはそれらのプロパティを継承します。

function Foo() {
    this.bar = "bar";
}
Foo.prototype.alertBar = function() {
    alert(this.bar);
}

var b = new Foo();
b.alertBar();

そのため、オブジェクトで明示的に定義されていなくても、bオブジェクトはメソッドを自動的に継承します。alertBar


関数をコンストラクターとして使用する必要はまったくありません。ご存知のように、リテラル構文を使用して 1 つのオブジェクトを作成できます。

コンストラクター関数を使用せずに継承を設定することもできます。単一の値セットからすべて継承するオブジェクトが必要だとします。でこれを実現できますObject.create

var base = {
    foo: "bar"
};

を使用Object.createして新しいオブジェクトを作成し、最初の引数として渡すbaseと、新しいオブジェクトは から継承されbaseます。

var a = Object.create(base);
var b = Object.create(base);
var c = Object.create(base);

a.foo; // "bar"
b.foo; // "bar"

したがって、コンストラクター関数なしでオブジェクトを作成できることがわかりますが、それでもプロトタイプ継承の利点が得られます。


最後に、関数を通常のコンストラクターとして実際に使用しなくても、関数を単純なオブジェクトと組み合わせて新しいオブジェクトを作成できます。これを行うには、関数がリテラル構文で作成されたオブジェクトを返すようにするだけです。

var fooMaker = (function() {

    var getBar = function() {
        return this.bar;
    };

    return function fooMaker() {

        return {
            bar: "bar",
            getBar: getBar
        };
    };
})();
var f = fooMaker();

f.getBar(); // "bar"
于 2012-12-07T15:03:55.513 に答える