JavaScript变量范围

时间:2013-01-09 07:08:12

标签: javascript oop instance-variables

我正在尝试构建一个简单的应用程序,我将创建一个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 );
}

请记住,它不能作为一个单身人士,因为我会在任何一个时间点拥有它的多个实例。

编辑:

我在构造函数中添加了事件监听器,更新了上面的代码。

3 个答案:

答案 0 :(得分: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事件将被传递抛出参数。

答案 1 :(得分: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 );
}

答案 2 :(得分:0)

你实际上有两个问题。

  

变量范围

JS中的变量总是具有函数范围。构造函数中的局部变量将保持构造函数的局部变量,并且不能在外部使用。

  

创建在每个单独对象中使用的全局变量

     

它不能充当单身人士

全局静态变量似乎与您想要的相反。我猜你的意思是 public 对象属性而不是 global 变量。所以使用一个:

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
 });

用于注册活动。