2

そのような関数のプロトタイプに追加できることを知っています

function main(){}
main.prototype.load = function()
{

}
...

と呼ばれる関数を実行しますmain.load

そのプロトタイプ内で関数のプロトタイプを作成することは可能ですか? 言い換えれば、私はこのようなことをすることができます:

main.prototype.get = function(){}
main.prototype.get.prototype.registration = function()
{
    // load registration info
}

main.get.registration();?を使用して関数を呼び出します。

これを実行しようとすると、コンソールに次のエラー メッセージが表示されます。

Uncaught TypeError: Object function (){} has no method 'registration'

編集: を呼び出した後にこれを行っていnew main();ます。だから私は次のようなことをするでしょう

var thisMain = new main();
thisMain.get.registration();
4

4 に答える 4

4

プロトタイプを少し誤解していると思います。

function が与えられた場合Foo、はオブジェクトFoo.prototypeのプロトタイプではありません。Fooを使用して作成されたオブジェクトに割り当てられるプロトタイプですnew Foo()。例えば:

// This is a constructor that creates objects whose prototype is Person.prototype
var Person = function(name) {
    this.name = name;
}
Person.prototype.sayHello = function() {
    console.log("Hello, my name is " + this.name);
}
var drew = new Person('Drew');
drew.sayHello();  // <-- Logs a message
drew.__proto__;   // <-- Not part of the Javascript spec, but it some browsers this is a reference to Person.prototype

main.get.registration は、プロトタイプなしで実装できます。

main = function() {/* do stuff*/}
main.get = function() {/* this is a getter function? */}
main.get.registration = function() {/* I don't know what this does */}

どのようなインターフェイスまたは API を作成したいと考えていますか? を使用してオブジェクトを作成する必要がありますnewか?

更新:これは、あなたが望むものを実装するための多くの可能な方法の1つです:

main = function() {
    // store a reference to this instance.
    var self = this;
    // Construct the get object.  It doesn't need to be a function because it's never invoked
    this.get = {};
    this.get.registration = function() {
        // Use self to refer to the specific instance of main you're interacting with.
        retrieveRegistrationFor(self); // <-- pseudo-code
    }
}

更新 2:getコンストラクターを使用してオブジェクトを構築し、すべてのプロトタイプを使用できるようにする方法を次に示します。コンストラクターの名前を大文字にしました。これは、通常の関数/メソッドとコンストラクターを区別するのに役立つベスト プラクティスです。

// Constructor for the get object.  This is only ever invoked in Main's constructor.
Getter = function(mainInstance) {
    this.self = mainInstance;
}
Getter.prototype.registration = function() {
    retrieveRegistrationFor(this.self); // <-- pseudo-code
}

Main = function() {
    // Construct the get object and attach it to this object.
    this.get = new Getter(this);
}

他の回答が指摘しているように、Javascript でオブジェクトを構築する方法はたくさんあります。それはすべて、状況と個人のコーディング スタイルによって異なります。

于 2013-03-08T03:21:40.360 に答える
0

これは私の個人的な意見にすぎませんが、JavaScript の典型的な継承モデルを理解するのは難しいといつも思っていました。コードを書いているときに推論するのは難しく、6 か月後にコードを維持するときに推論するのはさらに困難です。

ただし、あなたが求めているのは、「匿名クラスからメンバーのメソッドを継承するクラスを作成できますか?」ということだけです。このように言い換えると、アプローチに不確かな価値があることが明らかになると思います。クラスを記述する全体的な目的は、構成をタイトに保ちながら、単純な抽象化とカプセル化をサポートすることです。

従来のオブジェクトを使用する方が簡単です。

var main = { 
    get: {
        registration: function() {
            //TODO
        }  
    }
}

main.get.registration()パイのようにシンプルです。Object.create() と Object.defineProperties() を活用してこれを行うことができれば、なおさらです。

プロトタイプの継承を絶対に使用する必要がある場合は、Kistner 氏が提案する単純な Function.prototype 拡張機能が気に入っています。

Function.prototype.inheritsFrom = function(parentClassOrObject) {
    if (parentClassOrObject.constructor === Function) {
        //Normal Inheritance
        this.prototype = new parentClassOrObject;
        this.prototype.constructor = this;
        this.prototype.parent = parentClassOrObject.prototype;
    } else {
        //Pure Virtual Inheritance
        this.prototype = parentClassOrObject;
        this.prototype.constructor = this;
        this.prototype.parent = parentClassOrObject;
    }
    return this;
};

これにより、次のようにクラスと継承を構成できます。

/***
 * Method to create a Class with optional inheritance.
 * Generally, I oppose this semantic in JS:
 * partly because of the ineffability of the 'this' operator,
 * and partly because of the difficulty in grokking this.
 * What we're really saying here (through the wonders of functional programming) is this:
 *
 *      var MyClass1 = function(param1) {
 *          var ret = this;
 *          ret.id = param1;
 *          return ret;
 *      };
 *
 *      var MyClass2 = function(param1, param2) {
 *          var ret = this;
 *          MyClass1.apply(this, Array.prototype.slice.call(arguments, 0));
 *          ret.name = param2;
 *          return ret;
 *      };
 *
 *      MyClass2.prototype = new MyClass1;
 *      MyClass2.prototype.constructor = MyClass1;
 *      MyClass2.prototype.parent = MyClass1.prototype;
 *
 * I find this whole mode of operation as dull as it is stupid.
 * Nonetheless, there are occasions when the convention is suitable for type/instance checking
 *
 * Obviously, this method has very little utility if you are not using prototypal inheritance
*/
var MyClassCreatorMethod = function(name, inheritsFrom, callBack) {
    var obj = Object.create(null);
    obj[name] = function() {
        try {
            if(inheritsFrom ) {
                inheritsFrom.apply(this, Array.prototype.slice.call(arguments, 0));
            }
            callBack.apply(this, Array.prototype.slice.call(arguments, 0));
        } catch(e) {
            //do something
        }
    };
    if(inheritsFrom) {
        obj[name].inheritsFrom(inheritsFrom);
    }
    return obj[name];
};

ここから、継承されたクラスをデイジー チェーン接続するのは簡単になります。私は自分のプロジェクトの 1 つからこれを取り出したばかりなので、このセマンティクスのすべてが当てはまるわけではありません。これは、動作をより簡単に推論できるように機能化する方法を説明するためのものです。

于 2013-03-08T03:37:15.440 に答える
0

おそらくあなたがしたいことはこれです:

function main(){}
main.prototype.load = function()
{

};

main.prototype.get = function(){};
main.prototype.get.prototype.registration = function()
{
    // load registration info
    alert('hi, I\'m working');
};

var thisMain = new main();
var other = new thisMain.get();
other.registration();
于 2013-03-08T03:41:18.260 に答える
0

私はそれを動作させることができました

main.prototype.get.prototype.registration();

main.getただし、@the_system が述べたように、直接使用できないことを覚えておいてください。get関数 (および関数との類似性)を見つけるには、プロトタイプを調べる必要がありますregistration

于 2013-03-08T03:21:16.780 に答える