3

I am attempting to use the method invocation pattern in Javascript. I declare a function as an object member.

According to Javascript: The Good Parts, this should result in the this pointer referencing the enclosing object. When I've tried this before, this has been the case.

In the sample of code below, the this pointer reference by the single console.log statement is pointing to the function, not the object. I've double-checked my code and I honestly don't know what's going on.

I could use another pair of eyes on this. Is there something really obvious that I'm missing here, or am I expecting the wrong behavior? Thank you.

EDIT: I had a mistake in my code that I posted (it's been in flux); the keyword inside the anonymous function should be that, not this. Fixed.

DOUBLE EDIT: I've added the rest of my code within the module. I'm trying to write a commonJS module (in accordance with the gameJS library that I'm using) and although I'm not sure where that would be the problem, I'm wondering if it is. Does this change anything?

var gamejs = require('gamejs');
var system = require('app/system');

var input = {
    eval_keys: function () {
        console.log(this); // This should be the outer object, but shows the function!
        var that = this;
        gamejs.event.get().forEach(function (event) {
            if (event.type === gamejs.event.KEY_DOWN) {
                for (var key in that.keyconfig) {
                    if (that.keyconfig.hasOwnProperty(key)) {
                        if (event.key === gamejs.event[key]) {
                            that.keyconfig.key = true;
                        }
                    }
                }

                system.log("KEYDOWN", event.key);
            }

            if (event.type === gamejs.event.KEY_UP) {
                for (var key in that.keyconfig) {
                    if (that.keyconfig.hasOwnProperty(key)) {
                        if (event.key === gamejs.event[key]) {
                            that.keyconfig.key = false;
                        }
                    }
                }

                system.log("KEYUP", event.key);
            }

            return keyconfig;
        });
    },
    eval_mouse: function () {
/* in progress
        else if (event.type === gamejs.event.MOUSE_MOTION) {
            // if mouse is over display surface
            if (display.rect.collidePoint(event.pos)) {
                system.log("mousemove", testcoords);
                testcoords = event.pos;
            }
        }
*/
    },
    keyconfig: {
        K_UP: false,
        K_LEFT: false,
        K_RIGHT: false,
        K_DOWN: false
    }
};

exports.eval_keys = input.eval_keys;

Output from Chrome's dev console:

Object {eval_keys: function}
eval_keys: function () {
arguments: null
caller: null
length: 0
name: ""
prototype: Object
__proto__: function Empty() {}
<function scope>
__proto__: Object
4

3 回答 3

1

通过在声明对象后调用,它看起来我有用。input.eval_keys()

您在控制台中显示的输出在我看来也是您想要的输出——即Object {eval_keys: function}包含该方法的外部对象。

问题似乎更多的是您应该看到您在其中声明的其他方法,如下所示:

Object {eval_keys: function, eval_mouse: function, keyconfig: Object}
eval_keys: function () {
eval_mouse: function () {
keyconfig: Object
__proto__: Object

所以,据我所知,你的问题应该是“为什么这些其他方法没有出现在我的控制台对象中?” 但是我不知道您对可能解释该问题的代码所做的其他事情,也不知道您如何以及何时调用相关方法。

希望这可以帮助。

于 2013-03-24T18:12:42.750 回答
0

如果您没有在该forEach循环中使用匿名函数,它将起作用,this关键字在其中具有不同的值。您可以将它传递给第二个参数:

gamejs.event.get().forEach(function (event) {
    // this now refers to the outer this
}, this);

或者,您也可以使用that引用外部this值的变量。

于 2013-03-24T18:08:13.597 回答
0

好吧,我弄清楚了是什么导致this指针只显示一个具有一个函数的对象 - 就是这一行:

exports.eval_keys = input.eval_keys;

一时兴起,我决定添加exports.keyconfig = input.keyconfig它,它作为对象的一部分出现在控制台中。

看起来exports关键字在this引用它时对指针做了一些事情,即使this指针在相关模块内也是如此。我不完全确定它是如何工作的,但确实如此。

我遇到了更多问题,但目前,眼前的问题已经解决。我将不得不对此进行更多阅读。

于 2013-03-24T19:23:36.987 回答