如何在javascript成员函数中访问两个“ this”

时间:2018-09-06 09:11:15

标签: javascript

请查看以下代码段,

我有一个JavaScript类someFunc的方法someClass

在方法定义内btn变量的onclick处理程序中,我想同时引用SomeClass和按钮。

SomeClass.prototype.someFunc = function(){

    var btn = document.crealeElement("button");
    btn.onclick = function() {
       this.somePropertyOfSomeClass = true; //this works, because bind
       this.classList.add("active"); //this does not
    }.bind(this);
}

我知道,如果我使用bind(this),则单击处理程序中的this变量将指向SomeClass,并且在没有绑定的情况下,它将指向按钮元素。

我的问题是:如何同时获得两者?因为我想要处理程序中的类SomeClass的某些属性

5 个答案:

答案 0 :(得分:3)

访问事件正在通过(currentTarget)冒泡的元素(目标)或当前元素是一种更好,更现代的做法。除类实例外,在类内部是否使用this尚不清楚。另外,最好使用事件侦听器,以便可以附加相同类型的多个事件。

SomeClass.prototype.someFunc = function(){
    const btn = document.crealeElement("button");
    btn.addEventListener('click', (event) => {
       this.somePropertyOfSomeClass = true; //this works, because arrow function has lexical scope
       event.target.classList.add("active"); // proper way to access the element
    }
}

另外,您可能想看看ES6类。

答案 1 :(得分:1)

类似的事情应该起作用:

SomeClass.prototype.someFunc = function(){
    var that = this;

    var btn = document.crealeElement("button");
    btn.onclick = function() {
       that.somePropertyOfSomeClass = true; //references of SomeClass because of the closure
       this.classList.add("active"); //this should reference btn
    };
}

另请参阅@Dominic的帖子,这是一个更好的解决方案。

答案 2 :(得分:1)

只需将上下文保存在外部函数中即可:

SomeClass.prototype.someFunc = function(){
   let _this = this;
   var btn = document.crealeElement("button");
   btn.onclick = function() {
      _this.somePropertyOfSomeClass = true; //saved context
      this.classList.add("active");
   }
}

答案 3 :(得分:1)

将此代码this.classList.add("active");替换为btn.setAttribute("class", "active");

 SomeClass.prototype.someFunc = function(){

    var btn = document.crealeElement("button");
    btn.onclick = function() {
       this.somePropertyOfSomeClass = true; //this works, because bind
      btn.setAttribute("class", "active"); //this may be help you
    }.bind(this);
}

答案 4 :(得分:0)

由于您的代码是根据es5规范编写的,因此一种技术(不使用es6箭头函数,该函数根据定义的位置保留词法this)将其分配给您外部的变量事件处理程序。 (例如const self = this;),然后您可以引用self来引用类上的方法,或者引用this来根据需要触发dom事件的dom元素。由于您将在处理程序之外分配变量,因此变量在分配时将包含this的值,并且不会由处理程序的执行上下文确定。

注意:addEventListener是处理事件时的首选,因此您不受每个事件一个处理程序的限制,而是可以将多个处理程序附加到一个事件上。 Assignment via setters将替换之前设置的所有处理程序。

SomeClass.prototype.someFunc = function() {
    const self = this;
    const btn = document.crealeElement('button');
    btn.addEventListener('click', function() {
        self.somePropertyOfSomeClass = true;
        this.classList.add('active');
    });
}

如上所述,您还可以引用处理程序中的特定按钮,并选择不将函数绑定到类的this值,但这会使处理程序的通用性降低,这意味着只能使用它使用该特定按钮而不是任何按钮。