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 将保持它的上下文。click 事件将通过 throw 参数传递。

于 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

你实际上有两个问题。

可变范围

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 回答