2

独自のデータを制御および操作する Box オブジェクトの複数のインスタンスを作成する単純なアプリケーションを構築しようとしています。ただし、個々のオブジェクト内で使用するグローバル変数を作成する方法と、それに関連付けられているプロトタイプを作成する方法を理解するのに苦労しています...

たとえば、自分自身への参照を作成しようとしました...

function Box( boxData ) {
    // References the Box instance as I want.
    console.log( this );

    // I need to access this later...
    var boxName = boxData.name;

    var canvas = $( '#rm-' + boxData.id ).find( 'canvas' )[0];
    $( canvas ).on( 'mousedown', this.onMouseDownHandler );
}

Box.prototype.onMouseClickHandler = function( event ) {
    // 'boxName' is undefined as 'this' references 'event.target'
    console.log( this.boxName );
}

ある時点で複数のインスタンスがあるため、シングルトンとして機能できないことに注意してください。

編集:

上記のコードを更新して、コンストラクターにイベントリスナーを追加しています。

4

3 に答える 3

2

コンテキストとして Box インスタンスをキャンバスで使用するには、それをバインドする必要があります。

次のようなことを試すことができます:

function Box( boxData ) {
    // References the Box instance as I want.
    console.log( this );

    // I need to access this later...
    var boxName = boxData.name;

    // public property boxName
    this.boxName = boxName;

    var $canvas = $( '#rm-' + boxData.id ).find( 'canvas' );
    $canvas.on( 'mousedown', this.onMouseDownHandler.bind(this) );
    // ----------------------------------------------^
    // this bind will prevent the event use canvas element as context
}

function Room() {
    // some stuff
}

Room.prototype = new Box({name: 'this will always be my rooms box'});

Room.prototype.onMouseClickHandler = function( event ) {
    // 'boxName' is undefined as 'this' references 'event.target'
    console.log( this.boxName );
}

これで、これを試すことができます:

var foo = new Room();
foo.onMouseClickHandler();

そしてあなたのコンソールはログに記録しますthis will always be my rooms box.

Room は Box のインスタンスを拡張することに注意してください。

foo.boxName = 'my name is what?!';

// you changed the this so the prototype will get the new value:
foo.onMouseClickHandler(); // 'my name is what?!'

編集(質問のアップグレード後)

this.boxName代わりに単に使用してvar boxNameください:

function Box( boxData ) {
    // References the Box instance as I want.
    console.log( this );

    // public property boxName
    this.boxName = boxName;
}

また、他のオブジェクトに EventHandler を追加したいが、Box コンテキストを保持したい場合は、次のようにする必要があります。

var foo = newBox({boxName: 'foo'});
var bar = document.queryElementById('bar');

bar.addEventHandler('click', foo.onMouseClickHandler.bind(foo));

要素をクリックするとbar、foo の onMouseClickHandler がコンテキストを保持します。クリック イベントは、引数をスローして渡されます。

于 2013-01-09T07:17:06.310 に答える
0

グローバル オブジェクト (ウィンドウ) のプロパティとしてグローバル変数を作成します。window['box_instance_key']['name']すべてのインスタンスの名前を保存するために、次のようなものを使用できます。

function Box( boxData ) {
    // References the Box instance as I want.
    console.log( this );

    // I need to access this later...
    window.boxName = boxData.name;
    // or something like window[boxData.id]['boxName'] = boxData.name;
}

Room.prototype.onMouseClickHandler = function( event ) {
    // 'boxName' is undefined as 'this' references 'event.target'
    console.log( window.boxName );
}
于 2013-01-09T07:12:22.513 に答える
0

実際には 2 つの問題があります。

可変スコープ

JS の変数には常に関数スコープがあります。コンストラクター関数内のローカル変数は、コンストラクターに対してローカルのままであり、外部では使用できません。

個々のオブジェクト内で使用するグローバル変数を作成する

シングルトンとして機能することはできません

グローバルな静的変数は、あなたが望むものとは反対のようです。グローバル変数ではなく、パブリックオブジェクト プロパティを意味していたと思います。したがって、次のいずれかを使用します。

function Box( boxData ) {
    // References the Box instance as I want.
    console.log( this );

    // create a property to be accessed later...
    this.boxName = boxData.name;
}

'boxName' は、'this' が 'event.target' を参照しているため未定義です。

はい、関数のコンテキストはその呼び出しに (のみ) 依存します。使用する必要があります

 var that = this;
 ….addEventLister(…, function(event) {
      that.onMouseClick(); // "that" references the instance
 });

イベント登録用。

于 2013-01-09T07:26:09.677 に答える