繁体   English   中英

如何避免“ this”引用DOM元素并引用对象

[英]How to avoid “this” refering to the DOM element, and refer to the object

我有一个无法解决的问题。

上下文是:我想拥有一个继承链,并且属于该继承的对象的方法必须是事件处理程序,并且同时能够访问对象属性。

我正在尝试编写不带“新”字的JavaScript,并改为将Object.create()与某些继承层次结构一起使用。 所以首先是这种方法。

所以,我有我的其余对象(myProto)的蓝图,然后我创建的Object.create对象(所以没有封在那里我可以做到分配的把戏thisthatself )。 现在,当我使用该对象的方法来处理例如div上的click事件时, this显然将引用DOM对象,并且我失去了访问对象属性的可能性。

var myProto = {
    init: function (name, value) {
        this.name = name;
        this.value = value;

        return this;
    },
    someHandler: function (e) {
        // Normally I would use this instead of e.target...

        e.target.innerHTML = this.name + this.value; // This does not refer to the object.
    }
};

var myObject = Object.create(myProto).init('myName', 'myValue');
document.getElementById('myDiv').onclick = myObject.someHandler;

这里的小提琴: http : //jsfiddle.net/pgPHM/

现在是“经典”方法:如果我使用的是新的Constructor表单,则很容易在闭包中分配它然后访问它,但是存在Constructor.prototype中的函数的问题。

var Constructor = function (name, value) {
    var self = this;

    self.name = name;
    self.value = value;
};

Constructor.prototype.someHandler = function () {/*self does not reach this here*/};

jsfiddle: http : //jsfiddle.net/ZcG3J/2/

我真的不明白为什么JS对象在没有这些棘手的上下文,闭包等情况下没有真正的thisself或任何引用自己的东西...

基本上,问题是:

如何使用对象的方法作为事件处理程序,并且仍然能够访问该对象?

除了使用时newthis在Javascript中是按照函数是如何被调用设置。 称呼正确, this就是您想要的。 我真的不能告诉你想在你的问题来解决什么问题,但在这里是如何this是确定的。

  1. 调用obj.method() - this将在method()内部设置为obj
  2. 使用function.call()function.apply()控制一下this将是你自己。
  3. 进行正常的函数调用,例如func()this将被设置为全局对象或undefined具体取决于您是否处于严格模式下。
  4. 使用.bind() (在现代浏览器中)创建一个函数存根,该存根将在内部自动使用.apply()将其值“绑定”到函数执行中。
  5. 当您使用调用构造newthis将被设置为在构造函数中新创建的对象。
  6. 当你传递一个回调函数作为参数传递给任何函数调用(如addEventListener()它是调用函数有责任来决定它想要的this指针设置为,不会被绑定到自己的对象。 addEventListener() this设置为导致事件的DOM对象。

对于要成为特定对象上的方法调用的事件处理程序,必须创建一种将方法调用与该对象相关联的方法。 既可以使用.bind()如以上指定的,或使用可引用的保存的值的匿名函数this在封闭。

var self = this;
document.addEventListener('keyup', function(e) {
    self.handleKeys(e);
})

或者,使用.bind()

document.addEventListener('keyup', this.handleKeys.bind(this));

仅供参考,这两种方法之间没有任何实际的功能差异,因为.bind()只是创建了一个闭包,并且执行了第一个示例中的操作,但是为您完成了此操作。

简单。 如果某个函数被称为方法而不是“裸”,则this总是指最后一个点之前的单词。 所以代替:

document.getElementById('myDiv').onclick = myObject.someHandler;

// You're just passing the function here, not calling it.
// It will be called by the onclick handler so `this` is changed

做这个:

document.getElementById('myDiv').onclick = function(){
    myObject.someHandler();

    // Here, you're actually calling it. So this is the word
    // before the last dot. Which is myObject
}

在更现代的javascript中,您当然可以使用bind

document.getElementById('myDiv').onclick = myObject.someHandler.bind(myObject);

jsfiddle中的第一个问题是self是Constructor的局部变量,在函数外部不可用。 您对以下代码的看法:

var Constructor = function(name, value) {
    var self = this;
    self.name = name;
    self.value = value;
    self.someHandler = function(e) {
        e.target.innerHTML = self.name + self.value; // self undefined    
    }
    return self;
};

var myObject = Constructor('myName', 'myValue');
document.getElementById('myDiv').onclick = myObject.someHandler;

JsFiddle-> http://jsfiddle.net/ZcG3J/4/

是否按您想要的结构?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM