class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(state => ({
isToggleOn: !state.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);
官網有一段這個事件處理,有這個一句this.handleClick = this.handleClick.bind(this);需要在組件類的構造函數中自行綁定handClick的this指向,不加綁定的話通過打印測試this是undefined。官網解釋
You have to be careful about the meaning of this in JSX callbacks. In JavaScript, class methods are not bound by default. If you forget to bind this.handleClick and pass it to onClick, this will be undefined when the function is actually called.
在jsx中的回調方法沒有綁定this執行,而在普通的js class中的方法中的this如下
class T{
func() {
return this;
}
static staticFunc(){
return this;
}
constructor(){}
}
T.staticFunc() === T ; // true 未實例化之前的this
typeof T.staticFunc() === 'function'; // true 未實例化之前的this
typeof new T().func() === 'object'; // true 實例化之後的this
// 類其實就是原型的構造方法,一種語法糖
T.prototype.constructor === T; // true
// js沒有class之前構造一個對象,通過向函數的prototype原型裏面加方法,實例化之後可以調用,添加給prototype的屬性將會成爲使用這個構造函數創建的對象的通用屬性。
function T(x,y) {
this.x = x;
this.y = y;
}
T.prototype.sum = function () {
return this.x+this.y;
};
var p = new T(1, 2);
console.log(p.sum()); // 3
// 實例的__proto__指向構造函數的原型
console.log(p.__proto__ === T.prototype); // true
找到一個例子
var myObj = {
specialFunction: function () {
console.log(1);
},
anotherSpecialFunction: function () {
console.log(2);
},
getAsyncData: function (cb) {
cb();
},
render: function () {
this.getAsyncData(function () {
this.specialFunction();
this.anotherSpecialFunction();
});
}
};
myObj.render();
執行會報this.specialFunction is not a function,一種是將this賦值給一個變量,用變量取調用。
var myObj = {
specialFunction: function () {
console.log(1);
},
anotherSpecialFunction: function () {
console.log(2);
},
getAsyncData: function (cb) {
cb();
},
render: function () {
var that = this;
this.getAsyncData(function () {
that.specialFunction();
that.anotherSpecialFunction();
});
}
};
myObj.render(); // 1 2
不過更好的還是用Function.prototype.bind
var myObj = {
specialFunction: function () {
console.log(1);
},
anotherSpecialFunction: function () {
console.log(2);
},
getAsyncData: function (cb) {
cb();
},
render: function () {
this.getAsyncData(function () {
this.specialFunction();
this.anotherSpecialFunction();
}.bind(this));
}
};
myObj.render();