“this”在原型函数

时间:2016-11-25 14:30:21

标签: javascript asynchronous promise prototype

我想用异步包运行多个异步任务。 但我对javascript原型访问存在问题。

以下是我的代码示例:

var env = function(options) {
    this.options = options;
}

env.prototype.run = function() {
  
  var self = this,
  async.series([
    self.task1,
    self.task2
  ], function done(responses) {
      console.log(responses);
  });
}


env.prototype.task1 = function() {
  console.log(this.options); // undefined
  // logic code...
}



var foo = new env({foo: 'bar'});
foo.run(); // undefined - from console.log

不知道为什么我无法访问我的对象的'this'属性

1 个答案:

答案 0 :(得分:1)

此代码

async.series([
  self.task1,
  self.task2
], function done(responses) {
    console.log(responses);
});

只是将函数引用传递给async.series,但在调用它们时不会确保this是正确的。

除非您使用的async.series提供了告诉它使用this的方法,否则您可以使用bind轻松解决问题:

async.series([
  self.task1.bind(self),        // ***
  self.task2.bind(self)         // ***
], function done(responses) {
    console.log(responses);
});

这是一个更简单的示例,演示了问题和解决方案:

var obj = {
  property: "testing",
  wrong: function() {
    setTimeout(this.task1, 10);
  },
  right: function() {
    setTimeout(this.task1.bind(this), 20);
  },
  task1: function() {
    console.log("task1 says the property is " + this.property);
  }
};

obj.wrong();
obj.right();

附注:除非您使用self来展示run内未展示的内容,否则根本不需要它:

env.prototype.run = function() {
  async.series([
    this.task1.bind(this),
    this.task2.bind(this)
  ], function done(responses) {
      console.log(responses);
  });
};

如果您使用兼容ES2015的环境(或转换),另一个选择是将您的任务包装在箭头函数中:

// Requres ES2015 support
env.prototype.run = function() {
  async.series([
    (...args) => this.task1(...args),
    (...args) => this.task2(...args)
  ], function done(responses) {
      console.log(responses);
  });
};