2015-06-28 32 views
5

我想更好地瞭解this Firebase authenticator for Ember SimpleAuth當你在Ember函數上綁定'this'會發生什麼?

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(本)」在做什麼,綁定是如何工作的正是在這種特定情況下?

編輯:一點點思考和研究之後,這是我提出的東西可能會發生的解釋:

代碼的「那麼」部分沒有獲得的‘這種’原始上下文。 「.bind(this)」將「this」(在本例中爲當前控制器對象)的值設置爲「.then」函數內的「this」。

這可以通過以下事實來證明:如果「.bind(this)」部分被刪除,則代碼的「transitionTo」部分不起作用。

在另一方面,如果我們寫的代碼如下,我們並不需要使用 「.bind(本)」:

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'); 
     }); 
    } 
} 


}); 

的思考?

+0

是的,你應該添加你的文章的底部作爲答案(這很好回答你自己的問題)。 – steveax

回答

9

當你在Ember函數上綁定'this'會發生什麼?

在您的示例中,.bind()未用於Ember函數。它用於通常的匿名函數(回調函數)。因此,你的問題與Ember無關。

通過回調我的意思是一個匿名函數作爲參數傳遞而不是分配給對象的屬性。

這樣的函數將被綁定到window,即i。即該函數內的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()方法是在匿名函數外範圍內執行。它將函數綁定到外部範圍。因此,函數的內部作用域將與外部作用域相同,並且您可以照常使用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

+0

超清晰的解釋。謝謝。 – learningMachine

+0

好的。我已經接受並投票贊成。 – learningMachine

3

這正是發生的情況。如果你.bind(這個),那麼你不需要創建一個這個以外的函數的別名。進一步的解釋請參閱this question

相關問題