JavaScript的范围的addEventListener这(Javascript scope a

2019-07-17 12:19发布

我是一个C#开发者使用JavaScript实验和我试图让我的头周围的范围:)

我有以下的代码包含addEventListener中,我想用一个字段从我的对象:

(function(window) {

    function Keyboard() {
        this.keys = {};
    }

    Keyboard.prototype.handle_keydown = function(args) {
        this.keys[args.keyCode] = true;
    }

    Keyboard.prototype.listen = function() {
        window.addEventListener('keydown', this.handle_keydown);
    }

    app.util.keyboard = new Keyboard();

})(window);

我想用键数组在我的投手,但明白,我不能访问是利用这一点,因为这是在这方面的窗口(正确吗?)。 如果我将其更改为

app.util.keyboard.keys[args.keyCode] = true;

它的工作原理,但我不知道这是修复的好方法。

我发现这个问题 ,这似乎颇为相似,但是我不知道我怎么能适应它变成我的榜样。

谢谢你的帮助!

Answer 1:

一些东西:

  • 大多数人会认为像var self = this是因为它的快速和容易。

  • var self = this并不视图对象完全从视图逻辑 ,它从一个更加正式的C#背景的,看着你的代码中分离出来,听起来像你想要做的事。

  • 为了有回调只执行事件触发时,包裹处理的功能,因此,它的评估向右走,但只有在执行时,如果一个keydown事件触发(见下面的代码)。

  • 了解在JS范围:无论执行上下文,也是当前范围。 在方法(称为加入你的听众listen上) Keyboard.prototype ,但keydown事件实际上是对发射window -处理程序是在不同的上下文它被定义在那里执行; 它是什么调用它,在这种情况下,的上下文中执行的window ,所以它的作用范围window ,除非你通过其绑定到另一个对象bindapply时,它的定义。

在代码中, window是用户与交互的视图,并且Keyboard是该视图的控制器。 在MVC模式,比如你很可能在C#/。NET使用,意见不告诉自己,当事情发生的事,控制器告诉意见做什么。 所以,如果你是使用分配给控制器的参考var self = this像许多做,该视图将管理自身-但只针对特定处理器keydown事件。 这是不一致的,将成为难以在大项目管理。

一个办法:

Keyboard.prototype.listen = function() {
    window.addEventListener('keydown', function(e) {
        this.handle_keydown(e);
    }.bind(this), false);
}

更好的解决方案:

Keyboard.prototype.view = window;

Keyboard.prototype.listen = function() {
    this.view.addEventListener('keydown', function(e) {
        this.handle_keydown(e);
    }.bind(this), false);
}

最好的解决办法(直到ES6 class是准备好):

// define
function addViewController(view) {

    function ViewController() {

        this.handle_keydown = function(args) {
            // handle keydown events
        };

        this.listen = function() {
            this.view.addEventListener('keydown', function(e) {
                this.handle_keydown(e);
            }.bind(this), false);
        };

        this.view = view;
        return this;

    }

    return new ViewController(view);

}

// implement
var keyboard = addViewController(window);
keyboard.listen();
  • 注: .bind()是ECMAScript的5+兼容; 如果你需要对旧版浏览器的解决方案,Mozilla已经发布了一个伟大的替代.bind()使用functions.call()

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind

编辑:这是你的什么实例keyboard物体看起来像使用这个新的,模块化的解决方案:



Answer 2:

Keyboard.prototype.listen = function() {
    var self = this;
    window.addEventListener('keydown', function(event) {
       self.handle_keydown(event);
       // self is your Keyboard object. You can refer to all your properties from this
    });
}

如何此代码的工作:

  1. 我们正在创建自变量,它存储引用this变量。
  2. 内的功能是封闭的,因此它具有参考自我。
  3. 当封闭函数被调用: this指向DOM对象,而self指向键盘对象。
  4. 封闭被调用event为我们传递给键盘对象的成员函数的参数。


Answer 3:

怎么样

function Keyboard() {
    this.keys = {};
    var self = this;
    this.handle_keydown = function(args) {
        self.keys[args.keyCode] = true;
    }
    this.listen = function() {
        window.addEventListener('keydown', this.handle_keydown);
    }
}
app.util.keyboard = new Keyboard();


文章来源: Javascript scope addEventListener and this