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
有帮助吗?

解决方案

It looks like it does work to me, by calling input.eval_keys() after the object is declared.

Also the output you show in the console looks to me to be the output you want -- i.e., the outer object Object {eval_keys: function} containing the method.

The problem seems more to be that you should be seeing the other methods you declared in there, like this:

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

So, as far as I can tell, your question should be "why aren't these other methods showing up within my object in the console?" But I don't what else you are doing with the code that might account for that nor how and when you're invoking the relevant method.

Hope this helps.

其他提示

It would work if you didn't use an anonymous function with that forEach loop, the this keyword has a different value inside there. You can pass it in a the second parameter:

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

Alternatively you can use your that variable which refers to the outer this value as well.

Well, I figured out what was causing the this pointer to only show an object with one function - it was this line:

exports.eval_keys = input.eval_keys;

On a whim, I decided to add exports.keyconfig = input.keyconfig and it appeared in the console as part of the object.

It looks like the exports keyword does something with the this pointer when it's referenced, even if the this pointer is inside the module in question. I'm not exactly sure how that worked, but it did.

I'm running into more problems, but at the moment, the immediate issue has been resolved. I'll have to do some more reading on this.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top