0

私は JavaScript をしっかりと理解しようとしていますが、大きな問題に出くわしています。私は C 言語での作業に慣れていますが、JavaScript のプロトタイプ機能を処理することと、実行順序に関係する関数がいつ宣言されるかという障壁の 1 つを見つけています。

たとえば、次のコードを見てください。

var construct = new Constructor(); //I can do this even if its above the declaration of the object.

construct.MyPrivilagedFunction(); //Can do this here too, even though it's above the function declaration.

construct.MyPublicFunction(); //Can't do this because it is above the function declaration.

function Constructor() {

    //Private member
    var m_Ding = "Ding!";

    //Accessible publicly and has access to private member.
    this.MyPrivilagedFunction = function() {
    console.log(m_Ding);
    }
}
Constuctor.prototype.MyPublicFunction = function() {
    //Doesn't have access to private members. This doesn't work.
    console.log(m_Ding);
}

関数のコピーがオブジェクトのすべてのインスタンスに保存されるのではなく、代わりにすべてのインスタンスが同じ関数を参照しているため、プロトタイピングによりパフォーマンスが向上することを理解しています (そして、新しいインスタンスはそれぞれまったく新しいオブジェクト型と見なすことができると思いますか?) . ただし、プロトタイピングでは、関数を定義する前に使用することはできません。さらに、プロトタイプ化された関数は、オブジェクトのプライベート メンバーにアクセスできません。

2 つのオブジェクトが互いの関数を使用する必要があるプロジェクトに取り組んでいるため、これは本当に問題です。1 つのオブジェクトをコードの前に配置すると、2 番目のオブジェクトにアクセスできなくなります。これは、プロトタイプ化された関数が実行順序 (上から下) に従うためです。

補足: オブジェクトはおそらくオブジェクト リテラル (object={property:value} など) である必要があることも認識していますが、スコープをしっかりと把握し、それに対処するためのプロトタイプを作成しようとしています。今。

4

2 に答える 2

0

うまくいけば、問題の根本は「2つのオブジェクトがお互いの機能を使用する必要がある」ということです。

しかし実際には、Javascriptは型付き言語ではありません:TypeAを定義し、TypeBを定義します。その後、インスタンス:typeAおよびtypeBオブジェクトを問題なく使用できます。

var Speaker = function(name) {
    this.name = name ;
};

Speaker.prototype.sayHi = function(aMate) {
   amate.listenTo(this, ' Hi ' + this.mate.name ); // no type checking performed here
                                                   // so no issue even if Listener 
                                                   // is not defined yet
};

var Listener = function(name) {
    this.name = name;
    this.knownMate = [];
};

Listener.prototype.listenTo = function (mate, words) {
    this.knownMate.push(mate);
};

var aSpeaker  = new Speaker('Joe');
var aListener = new Listener('Bobby');

aSpeaker.sayHi(aListener);

ちなみに、Javascriptにはプライベートメンバーはなく、クロージャだけがあります。したがって、「private」メンバーのスコープ外で定義された関数は、そのメンバーに対して読み取り/書き込みを行うことができません。
また、パフォーマンスが問題になる場合は、パフォーマンスの低いjsエンジンではクロージャの速度が遅くなることにも注意してください。'pseudo-private'メンバーを持つためのそれほど悪くない解決策は、それらのメンバーをObject.defineProperty()で列挙できないものとして定義することです(
ここを見てください:
https ://developer.mozilla.org/en-US/docs/JavaScript / Reference / Global_Objects / Object / defineProperty

于 2013-03-03T10:49:36.190 に答える
0

実行順序はあなたが書いたものです。「下にあるものはすべて無関係」というルールからの例外が 2 つだけあります。変数と関数の宣言は巻き上げられます。また、関数宣言と関数式の違いに注意してください。

var construct = new Constructor() //I can do this even if its above the declaration of the object.

言いたいコンストラクタ関数の宣言。

construct.MyPrivilagedFunction(); //Can do this here too, even though it's above the function declaration.

ここには関数宣言はありません。特権メソッドは、コンストラクター関数の実行中に (関数式をプロパティに割り当てて) 作成されました (上記を参照)。

construct.MyPublicFunction(); //Can't do this because it is above the function declaration.

繰り返しますが、これは関数宣言ではなく、関数式の代入です。それは下にあるので、まだ起こりませんでした。

2 つのオブジェクトが互いの関数を使用する必要があるプロジェクトに取り組んでいるため、これは本当に問題です。1 つのオブジェクトをコードの前に配置すると、2 番目のオブジェクトにアクセスできなくなります。これは、プロトタイプ化された関数が実行順序 (上から下) に従うためです。

通常、何かを呼び出す前に、何かにアクセスする必要はありません。最初にすべて (コンストラクター、プロトタイプ プロパティ) を "宣言" し、次にインスタンス化します。

于 2013-03-03T11:35:20.507 に答える