5

次の名前のファイルに次のようなものがあるとしましょうmain.js

function obj_name() {}

obj_name.prototype = {
    foo  : function() { alert('hi!'); },
    foo2 : function() { alert('hi again!'); }
}

今、私は別のファイルでオブジェクトを展開するためにこの方法を試みていますextend.js

obj_name.prototype = {
    newfoo : function() { alert('hi #3'); }
}

...しかし、問題は、このようにコーディングすればうまくいくということです。

obj_name.prototype.newfoo = function() { alert('hi #3'); }

私はこれが初心者の質問かもしれないと思います。これがオブジェクトを拡張する適切な方法であるかどうかさえわかりませんが、なぜこれが発生するのか疑問に思っています。

よろしくお願いします。

4

4 に答える 4

7

jQueryを使用しない別のオプション:

var extend = function(destination, source)
{
    for (var property in source)
    {
        if (destination[property] && (typeof(destination[property]) == 'object')
                && (destination[property].toString() == '[object Object]') && source[property])
            extend(destination[property], source[property]);
        else
            destination[property] = source[property];
    }
    return destination;
}

var a = {a: 'test'};                              // original
var b = {newFoo: function() { alert('hi #3'); }}; // the addition
extend(a, b);                                 // extend it
a.newFoo();                                   // call the added property
于 2011-05-12T08:56:27.180 に答える
5

これは、列にあるためです

obj_name.prototype = {
    newfoo : function() { alert('hi #3'); }
}

新しいプロトタイプオブジェクトを作成し、プライベートコンテンツを削除します。それはあなたが言ったかのようです

var a = {};

次のようなオブジェクトを拡張するとき

obj_name.prototype.newfoo = function() { alert('hi #3'); }

オブジェクトツリーに新しいプロパティ(newfoo)を追加するだけで、既存のコンテンツは変更されません。これが機能する理由です

HTH

Ivo Stoykov

于 2011-05-12T08:53:12.683 に答える
4

最初の方法では、プロトタイプを新しいものと交換します(以前にあったものを上書きします)。2番目の方法では、プロトタイプに新しいメンバーを追加します(したがって、プロトタイプを拡張します)。

別のメソッドがあります。メソッドなどを備えたライブラリですextend(基本的に、2番目のフォームで実行していることを素敵なラッパーでラップします)。たとえば、jQueryでは:

$.extend(obj_name.prototype, {
    newfoo : function() { alert('hi #3'); }
}
于 2011-05-12T08:39:47.803 に答える
1

これを正確に提供するシンプルで軽量なライブラリを探している場合:JavaScriptで「正しく行われた」OOP、これを見てください:https ://github.com/haroldiedema/joii

githubページのreadmeで提供されているソースコードの例と、次のリンク:

このライブラリでは、基本的に「クラス」を次のように定義できます。

var Person = Class(function() {
    this.firstname = "John"
    this.surname   = "Smith"
    this.role= "Developer"

    this.getInfo = function() {
        return this.firstname + ' ' + this.surname + ' is ' + this.role;
    };
});

var AnotherPerson = Class({ extends: Person }, function() {
    this.firstname = "Bob";
});

var p = new AnotherPerson();
console.log(p.getInfo());
// Bob Smith is Developer

編集

コードを例として取り上げますが、JOII互換のコードに変換すると、次のようになります。

var obj_name = Class(function() {
    this.foo = function() { alert('hi!'); };
    this.foo2 = function() { alert('hi again!'); };
};

var obj_name2 = Class({ extends: obj_name }, function() {
    this.newfoo = function() { alert('hi #3'); };
});

var o = new obj_name2();
o.foo(); // hi!
o.newfoo(); // hi #3

または、ミックスインとして使用します。

var o = new obj_name();
o.mixin(obj_name2);

o.newfoo(); // hi #3

またはその逆で、「特性」を使用します。

// the "uses" option basically copies content from the given object to the scope of your "class", solving the horizontal code-reuse problem.
var obj_name = Class({ uses: [obj_name2], function() {
    this.foo = function() { alert('hi!'); };
    this.foo2 = function() { alert('hi again!'); };
});

var o = new obj_name();
o.newfoo(); // hi #3
于 2014-04-16T17:27:44.790 に答える