整理一下javascript
(包括ES3
、ES5
、ES6
)中的this
問題。javascript
這個版本的this
很明確,只有如下五種狀況:java
console.log(this); // this 等於 ECMAScript 在瀏覽器環境的 Global 對象,即 window
複製代碼
function foo() {
console.log(this); // this 仍是 window
}
複製代碼
var obj = {
name: 'alex',
getName: function(){
console.log(this.name);
}
}
obj.getName(); // this 爲 obj
var bar = obj.getName;
bar(); // 用這種方式調用,this 就指向了 window,由於這樣調用時,函數的執行環境是全局的
複製代碼
function Foo() {}
Foo.prototype.getName = function(){
console.log(this.name);
}
var bar = new Foo();
bar.name = 'alex';
bar.getName(); // this 指向實例 bar
複製代碼
apply
和call
改變函數運行時的this
指向react
function foo(){
console.log(this.name);
}
var applyObj = {
name: 'alex'
}
var callObj = {
name: 'f0rest'
}
foo.apply(applyObj); // alex
foo.call(callObj); // f0rest
複製代碼
在ES 6
,咱們大部分函數的寫法都是使用箭頭函數(arrow function
),它的this
不一樣於ES 5
。瀏覽器
// ES 5
var foo = function(options){ console.log('alex'); };
// ES 6
const foo = (options) => { console.log('alex'); };
// ES6 function to return a object
const foo = () => ({ name: 'f0rest' });
複製代碼
ES 6
中的規則是,緊隨箭頭的{
被解析爲塊的開始,而不是對象的開始,因此小括號包裹對象字面量是惟一一個你須要牢記的小竅門app
箭頭函數它沒有本身的this
值,它繼承外圍做用域的this
函數
下面這個例子,this
爲undefined
,由於ES 6
是嚴格模式,嚴格模式下全局做用域的this
爲undefined
ui
const foo = (options) => {
console.log(this); // undefined
};
複製代碼
React
中的實踐在React
組件中,註冊事件有三種方式,目的是讓事件函數內的this
指向這個當前組件實例this
咱們用
ES 6
的語法來進行react
應用開發spa
在constructor
方法中綁定prototype
class App extends React.Component {
constructor() {
this.myEvent = this.myEvent.bind(this);
}
myEvent() {
console.log(this);
}
render() {
return (<div onClick={this.myEvent}>demo</div>);
}
}
複製代碼
在render
方法中綁定,由於render
方法已經爲你綁定了this
class App extends React.Component {
myEvent() {
console.log(this);
}
render() {
return (<div onClick={this.myEvent.bind(this)}>demo</div>);
}
}
複製代碼
這裏就是箭頭函數,繼承外圍做用域的 this,即當前組件實例
class App extends React.Component {
myEvent = () => {
console.log(this);
}
render() {
return (<div onClick={this.myEvent}>demo</div>);
}
}
複製代碼
注: 若是你寫的是通用組件,推薦第一種方式,這涉及原型的相關內容,暫且不表。
謝謝閱讀,若有謬誤,懇請斧正。