Javascript“this"方法调用模式中的指针没有指向对象

Javascript "this" pointer in Method Invocation Pattern not pointing to object

本文关键字:指针 对象 模式 this quot 调用 方法 Javascript      更新时间:2023-09-26

我试图在Javascript中使用方法调用模式。我将函数声明为对象成员。

根据Javascript: The Good Parts,这应该导致this指针引用封闭对象。当我以前尝试过的时候,情况就是这样。

在下面的代码示例中,单个console.log语句引用的this指针指向函数,而不是对象。我已经仔细检查了我的代码,我真的不知道是怎么回事。

我可以用另一双眼睛看这件事。是我忽略了什么明显的东西,还是我期望错误的行为?谢谢你。

编辑:我在我发布的代码中有一个错误(它一直在变化);匿名函数内部的关键字应该是that,而不是this。固定的。

DOUBLE EDIT:我已经在模块中添加了其余的代码。我试图写一个commonJS模块(按照我正在使用的gameJS库),虽然我不确定这将是问题所在,我想知道它是否是。这会改变什么吗?

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;

Chrome的开发控制台输出:

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

通过在对象声明后调用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

所以,据我所知,你的问题应该是"为什么这些其他方法不在控制台的对象中显示?"但是我不知道你在代码中做了什么,也不知道你是如何以及何时调用相关方法的。

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

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

或者你可以使用你的that变量,它也引用外部的this

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

exports.eval_keys = input.eval_keys;

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

看起来exports关键字在this指针被引用时做了一些事情,即使this指针在有问题的模块内部。我不太确定这是怎么回事,但它确实做到了。

我遇到了更多的问题,但目前,最紧迫的问题已经解决了。