React handling events關於js中this的一些思考

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(); 

參考文章

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章