2013-01-09 36 views
2

我想构建一个简单的应用程序,我将创建一个Box对象的多个实例,它将控制和操作自己的数据。然而,我无法搞清楚如何将每个独立的对象中创建使用全局变量和它相关的原型......JavaScript变量作用域

例如,我试图让自身的参考...

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

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

编辑:

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

+0

你是如何执行你的Box.onMouseClickHandler?我认为你没有把它绑定正确,但需要一个例子来找出你得到错误的地方。请给出一个使用示例。 –

+0

更新了事件监听器 – user1960364

回答

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

不会window.boxName干扰其他Box实例吗?并且在您的评论中,您说使用box_instance_key - 但是如何从实例中获取实例密钥? – user1960364

+0

@ user1960364是的,这就是为什么我向顶部添加注释,说您可以使用某种实例ID来分隔它们。我用评论更新了代码。 –

+0

对不起,原型应该是Box.prototype ...更新了问题。 因此,我仍然不确定如何从原型中获取boxData.id。 – user1960364

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

你记住,房间扩展盒的一个实例,因此,如果你这样做:

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

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

EDIT(问题升级后)

只需使用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元素,从富的onMouseClickHandler点击,将保持它的上下文。点击事件将通过抛出参数。

+0

对不起,我更新了最初的问题。原型和构造函数都应该说Box ... – user1960364

+0

@ user1960364好的,答案也更新了。 –

+0

问题是,'this'在事件处理程序中使用时没有引用Box对象实例。 – user1960364

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' 未定义 '本次' 引用 'event.target'

是,该功能的情况下取决于(只)在它的调用。您将需要使用

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

注册事件。

+0

你也可以绑定上下文,所以调用不会触及它。 –