我对bindMeteor.bindEnvironment的行为以及thisMeteor.bindEnvironment的作用域感到困惑。例如,with arrow functions, arrow functions should maintain the outer scope


  从本质上讲,它允许您使用上下文值“ this”创建匿名函数,该上下文值是函数的范围,而该范围是定义箭头函数的外部函数的范围。


因此,当我使用以下代码时,它似乎可以工作,但是console.log似乎说this是流星的范围。

Cylon = new EventEmitter();
Cylon.messages = new Mongo.Collection('_cylon_messages');
Cylon._commands = net.connect(Settings.connection);
Cylon._createConnection = function (name, connection) {
  let socket = net.connect(connection, Meteor.bindEnvironment(() => {
    this.messages.insert({ name: name, message: 'connected'})
  }));
  socket._name = name;
  return socket;
}


我一直难以理解的另一个示例是在需要Meteor.bindEnvironment的回调中使用bind。例如:

Cylon.execute = function (routine) {
  check(command, String);
  let future = new Future();
  let done = future.resolver();
  this.once('End', Meteor.bindEnvironment(done.bind(null, routine)));
  this._commands.write(`XQ#${routine}\r`, 'utf8');
  future.wait();
  this.removeListener('End', Meteor.bindEnvironment(done.bind(null, routine)));
  return future;
}


Meteor.bindEnvironment如何将this绑定到函数?有适当的用法吗?

最佳答案

什么是箭头功能?

这是一个非常令人困惑和冗长的句子:


  从本质上讲,它允许您使用上下文值“ this”创建匿名函数,该上下文值是函数的范围,而该范围是定义箭头函数的外部函数的范围。


通过将其浓缩为更简洁的语言,可以使其更易于理解:


  它允许您创建一个匿名函数,该匿名函数按词法绑定到定义它的作用域。


________

Arrow Functions解释

您提供的示例中没有console.log-大概是在console.log的箭头函数中放置了bindEnvironment,如下所示:

let socket = net.connect(connection, Meteor.bindEnvironment(() => {
    console.log(this);
    // this.messages.insert({ name: name, message: 'connected'});
}));


实际上,以上示例中的this是对arrow函数执行上下文的引用。例如:

this.stillInScope = true;
let socket = net.connect(connection, Meteor.bindEnvironment(() => {
    console.log(this.stillInScope); // => 'true'
}));


但是,假设我们将arrow函数更改为匿名函数。调用时,它将不维护对其声明时存在的执行上下文的访问:

this.stillInScope = true;
let socket = net.connect(connection, Meteor.bindEnvironment(function () {
    console.log(this.stillInScope); // => 'undefined'
}));


因此,如果此示例的当前执行上下文是Meteor对象,则arrow函数将按词法绑定到Meteor对象:

// this instanceof Meteor === true
let socket = net.connect(connection, Meteor.bindEnvironment(() => {
    console.log(this instanceof Meteor); // => 'true'
}));


________

bind方法介绍

让我们讨论一下为什么要使用bind来理解第二个示例中实现的目标。

bind的第一个参数:执行上下文

在方法上使用bind会产生一个新函数,该函数绑定到第一个参数定义的执行上下文。假设我们在全局执行上下文为window的浏览器中运行此命令:

let method = function () {
    console.log(this);
};

method(); // => window

let boundMethod = method.bind('Hello'); // `this` now becomes 'Hello'
boundMethod(); // => 'Hello'


此绑定永远无法更改;而不是通过绑定函数内的调用,甚至不是随后对bind的调用。

bind的后续参数:默认参数

在示例中,您给出的bind实际上仅用作速记。我们可以知道这是因为给定的执行上下文是null,表明bind仅用于将默认参数应用于函数的方式:

// with `bind`
Meteor.bindEnvironment(done.bind(null, routine))

// without `bind`
Meteor.bindEnvironment(function () {
    done(routine);
});


________

bind如何与Meteor.bindEnvironment一起使用?

最后,要回答您的问题,bind本身并不会“处理”任何内容。 Meteor.bindEnvironment接受赋予它的功能,并将其绑定到由闭包维护的执行上下文,在闭包中最初定义了方法bindEnvironment

An explanation of the purpose of Meteor.bindEnvironment on GitHub


  bindEnvironment的想法是,在将回调传递给非Meteor代码时,可以使它们在当前上下文中运行。在包含当前光纤的服务器上。因此,如果您发现自己不在服务器上的Fibre之外,则可能未充分调用bindEnvironment!


通过为它提供已绑定的功能(作为箭头功能或通过手动传递bind的功能),可以防止其更改功能的执行上下文。

关于javascript - 绑定(bind)如何与Meteor.bindEnvironment一起使用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32822823/

10-11 05:46