javascript - 当您在 Ember 函数上绑定(bind) 'this' 时会发生什么?

标签 javascript

我正在努力更好地理解 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/

相关文章:

Javascript::将回调后的 JSON 字符串转换为纯 JavaScript 数组

javascript - Leaflet——获取经纬度的前三位小数

javascript - 为什么我无法在事件回调中捕获 discord.js promise 拒绝?

javascript - Angularjs检查数组中是否存在传递值

javascript - 滚动到顶部未生效

javascript - 您如何处理通过 AJAX 保存与尚未创建的对象相关的属性?

javascript - Array.prototype.includes 函数如何比较对象

javascript - 如何使用 JQuery 追加 ajax 成功响应后聚焦到 div

javascript - Ext JS - 将面板绑定(bind)到数据存储的最佳方式

javascript - 使外部脚本可供 qooxdoo 对象的所有成员使用