Javascript'这个'返回undefined内部对象

时间:2018-04-20 10:49:28

标签: javascript object ecmascript-6 this arrow-functions

我有以下代码:

let myObj = {
  foo: "bar",
  getFoo: function() {
    console.log(this.foo);
  },
  method: function() {
    if (true) {
      window.addEventListener('scroll', this.getFoo);
    } else {
      window.removeEventListener('scroll', this.getFoo);
    }
  }
}

window.addEventListener('click', () => {
  myObj.method();
});

它返回undefinded,因为(由于我不知道的原因)this如果在window函数中调用getFoo作为回调,则引用addEventListener对象。 现在,如果我在myObj.method -

中使用了箭头功能
window.addEventListener('scroll', () => {
  this.getFoo();
});

这样可行,但后来我调用了一个匿名函数,以后不能removeEventListener。 我如何才能使用非匿名函数?

4 个答案:

答案 0 :(得分:2)

来自MDN

  

箭头函数表达式的语法短于函数表达式,并且没有自己的thisargumentssupernew.target。这些函数表达式最适合非方法函数,不能用作构造函数。

答案 1 :(得分:1)

您可以使用callbind在某个对象的上下文中调用方法或函数,以便this引用myObj的上下文:

let myObj = {
  foo: "bar",
  getFoo: function() {
    console.log(this.foo);
  },
  method: function() {
    if (true) {
      // here you have to use bind to create a function in a certain context
      window.addEventListener('scroll', this.getFoo.bind(this));
    } else {
      // here is the same
      window.removeEventListener('scroll', this.getFoo.bind(this));
    }
  }
}

window.addEventListener('click', () => {
  // create and call method in the context of myObj or any other object that is passed as first parameter of call
  myObj.method.call(myObj);
  // or because this in the function method refers to myObj at the beginning, just call method with obj
  myObj.method();
});

答案 2 :(得分:0)

我建议你快速查看here,如果你想知道"这个"关键字实际上有效...

您的问题的解决方案可能是创建一个名为selfObj的变量(或类似的东西),然后使用它来访问myObj的属性。

编辑:此版本经过测试并可以使用。不确定它是否已经足够简单了...这里的关键是将完全相同的参数传递给addEventListenerremoveEventListener。出于这个原因,我为scrollEventListener对象创建了myObj数组属性。然后使用destructuring传递它作为参数...

希望这会有所帮助......

'use strict';

    let myObj = {
        foo: 'bar',
        counter: 0,
        getFoo: function() {
            const selfObj = this;
            console.log(selfObj.foo);
        },
        scrollEventListener: [
            'scroll',
            function () {
                myObj.getFoo();
            },
            true
        ],
        method: function() {
            const selfObj = this;
            selfObj.counter++;
            if (selfObj.counter % 2 === 0) {
                window.addEventListener(...selfObj.scrollEventListener);
            } else {
                window.removeEventListener(...selfObj.scrollEventListener);
            }
        }
    };

    window.addEventListener('click', () => {
        myObj.method();
    });

答案 3 :(得分:-1)

如果匿名函数中有thisthis指向窗口,而不指向您定义它的对象。与使用function相比,this绑定到您定义此函数的对象。