我正在努力更好地理解 this Firebase authenticator for Ember SimpleAuth :
import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
login: function() {
this.get('session').authenticate('authenticator:firebase', {
'email': this.get('email'),
'password': this.get('password')
}).then(function() {
this.transitionToRoute('index');
}.bind(this));
},
logout: function() {
this.get('session').invalidate().then(function() {
this.transitionToRoute('login');
}.bind(this));
}
}
});
谁能解释一下“.bind(this)”在做什么,以及 bind 在这个特定实例中是如何工作的?
编辑:经过一些反射(reflection)和研究,这是我对可能发生的事情提出的解释:
代码的“.then”部分无法访问“this”的原始上下文。 “.bind(this)”将“this”(在本例中为当前 Controller 对象)的值设置为“.then”函数内的“this”。
如果删除“.bind(this)”部分,代码的“transitionTo”部分将不起作用,这一事实可以证明这一点。
另一方面,如果我们编写如下代码,就不需要使用 “.bind(this)”:
import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
login: function() {
var _this = this;
this.get('session').authenticate('authenticator:firebase', {
'email': this.get('email'),
'password': this.get('password')
}).then(function() {
_this.transitionToRoute('index');
});
},
logout: function() {
var _this = this;
this.get('session').invalidate().then(function() {
_this.transitionToRoute('login');
});
}
}
});
想法?
最佳答案
What happens when you bind 'this' on an Ember function?
在您的示例中,.bind()
未用于 Ember 函数。它用于通常的匿名函数(回调)。因此,您的问题与 Ember 无关。
我所说的回调是指作为参数传递的匿名函数,而不是分配给对象的属性。
这样的函数会绑定(bind)到window
,即。 e.函数中的 this
将返回 window
。
访问外部作用域的传统方法是将 this
分配给外部作用域中的变量,然后访问内部作用域中的变量:
var _this = this;
someMethod(function() {
console.log(this); // => window
console.log(_this); // => Outer scope
});
当您需要访问内部和外部范围时,这种方法很好。但是内部作用域没有任何用处,所以我们可以写得更短:
someMethod(function() {
console.log(this); // Outer scope
}.bind(this));
.bind()
方法在 anon 函数的外部作用域中执行。它将函数绑定(bind)到外部范围。因此,函数的内部作用域将与外部作用域相同,您可以像往常一样使用 this
,就好像作用域没有改变一样。
在 CoffeeScript 中,您可以使用粗箭头留在外部作用域中:
_this = this
someMethod ->
console.log this # winodw
console.log _this # Outer scope
someMethod =>
console.log this # Outer scope
console.log ` this ` # You can still access window like ` this `, pun intended
在 ES6 中你也可以使用粗箭头:
foo( () => {
console.log(this);
});
请注意,虽然像在 CoffeeScript 中一样,粗箭头维护着外部作用域,但这意味着不同的东西!在 ES6 中,粗箭头创建了一个无法拥有自己作用域的假函数。
这很重要,因为一些库通过将回调应用到特定范围来与回调通信,并希望您对其执行 this.something()
。它不适用于 ES6 粗箭头(好吧,它在技术上可以与 Babel 一起使用,因为 Babel 将 ES6 粗箭头转换为传统函数,但你不应该依赖它)。
有关 .bind()
的更多信息,请参阅 Function.prototype.bind() on MDN .
关于javascript - 当您在 Ember 函数上绑定(bind) 'this' 时会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31100243/