TypeError:不是函数。绑定这个的正确方法。 JS中的引用

时间:2017-05-31 12:21:47

标签: javascript typescript

我是JS的新手,所以我有关于绑定引用的正确方法的新手问题。例如,我在TypeScript中有这行代码:

  this.socket.on('new_task').subscribe(this.newTask);
...
  newTask(data) {
    this.logEvent('new_task', data);
    this.audio.playNewJob();
  }
  logEvent(event: string, data) {
    console.log(this.TAG + event + ' triggered with received data: ' + JSON.stringify(data));
  }

如果我试试这个,我会得到:

TypeError: this.logEvent is not a function

如果我改为:

this.socket.on('new_task').subscribe((data) => this.newTask(data));

一切都会正常工作,但它看起来像是使用JS和TS功能的坏方法。在这种情况下,推荐的做法是什么?

3 个答案:

答案 0 :(得分:2)

将其更改为

.subscribe(this.newTask.bind(this))

答案 1 :(得分:2)

问题是“this”是如何绑定的,它是在执行时完成的,因此当调用logEvent函数时,它指的是没有该函数的全局对象。你的第二个例子很好,在这种情况下,当箭头函数被定义时,这是绑定的,另一种方法是存储对此的引用并从中调用函数,但我个人更喜欢箭头函数方法。请注意,不是每个人都同意这一点,但我习惯于从c#中选择箭头函数,我想如果你理解他们阅读的差异更容易,并且有更简单的推理方法。

答案 2 :(得分:0)

我使用 属性 而不是 method 面对此问题。即我们可以使用"属性语法" 来声明一些相同的功能。其中property是一个函数(newTask下面是方法,newTaskAsProperty是更多属性 - ISH)的

class MyClass {
    newTask(data) {
        this.logEvent('new_task', data);
        this.audio.playNewJob();
    }    
    newTaskAsProperty = (data) =>{
        this.logEvent('new_task', data);
        this.audio.playNewJob();
    }
    ...

有趣的是,结果是什么:

var MyClass = (function () {
    function MyClass() {
        var _this = this;
        this.newTaskAsProperty = function (data) {
            _this.logEvent('new_task', data);
            _this.audio.playNewJob();
        };
    }
    MyClass.prototype.newTask = function (data) {
        this.logEvent('new_task', data);
        this.audio.playNewJob();
    };

因此,属性方法(newTaskAsProperty = (data) =>{})在构造函数中应用于实例,而不是原型。也就是说,为什么使用作为代理将按预期工作

// not working
// this.socket.on('new_task').subscribe(this.newTask);

// working
this.socket.on('new_task').subscribe(this.newTaskAsProperty);

唯一的缺点是 - 不是方法,即无法覆盖。

作为一种解决方法,我们可以简单地在其中调用一个真正的方法 - 如果需要,并且该方法可以正确设置 this 并且可以覆盖......