我正在尝试更好地理解Ember SimpleAuth的Firebase身份验证器:
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));
}
}
});
Run Code Online (Sandbox Code Playgroud)
有人请解释".bind(this)"正在做什么,以及在这个特定实例中究竟绑定是如何工作的?
编辑:经过一番反思和研究,这是我对可能发生的事情的建议解释:
代码的".then"部分无法访问"this"的原始上下文.".bind(this)"将"this"(在本例中为当前控制器对象)的值设置为".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');
});
}
}
});
Run Code Online (Sandbox Code Playgroud)
思考?
在Ember函数上绑定'this'会发生什么?
在您的示例中,.bind()未在Ember函数上使用.它用于通常的匿名函数(回调).因此,你的问题与Ember无关.
通过回调,我的意思是作为参数传递的匿名函数,而不是分配给对象的属性.
这样的函数将被绑定window,即this函数内将返回window.
访问外部作用域的传统方法是分配外部作用域中this的变量,然后访问内部作用域中的变量:
var _this = this;
someMethod(function() {
console.log(this); // => window
console.log(_this); // => Outer scope
});
Run Code Online (Sandbox Code Playgroud)
当您需要访问内部和外部范围时,此方法很好.但是内部范围没什么用处,所以我们可以把它写得更短:
someMethod(function() {
console.log(this); // Outer scope
}.bind(this));
Run Code Online (Sandbox Code Playgroud)
该.bind()方法在anon函数的外部范围内执行.它将函数绑定到外部范围.因此,函数的内部范围将与外部范围相同,并且您可以this像往常一样使用,就好像范围没有改变一样.
在CoffeeScript中,您可以使用胖箭头保留在外部范围内:
_this = this
someMethod ->
console.log this # winodw
console.log _this # Outer scope
Run Code Online (Sandbox Code Playgroud)
someMethod =>
console.log this # Outer scope
console.log ` this ` # You can still access window like ` this `, pun intended
Run Code Online (Sandbox Code Playgroud)
在ES6中你也可以使用胖箭头:
foo( () => {
console.log(this);
});
Run Code Online (Sandbox Code Playgroud)
请注意,虽然在CoffeeScript中胖箭头保持外部范围,但它意味着不同的东西!在ES6中,胖箭头创建了一个无法拥有自己范围的虚假函数.
这很重要,因为一些库通过将回调应用于某个范围来与回调进行通信,并期望您对其进行操作this.something().它不适用于ES6胖箭(嗯,它可以在技术上与Babel一起使用,因为Babel将ES6胖箭转换为传统功能,但你不应该依赖它).
有关更多信息.bind(),请参阅MDN上的Function.prototype.bind().