我对bind
和Meteor.bindEnvironment
的行为以及this
和Meteor.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/