javascript面向对象详解--this

in JavaScript with 0 comment

先来看一个现象,初学React的肯定会遇到在constructor进行bind的操作

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // 为了在回调中使用 `this`,这个绑定是必不可少的, bind是永久绑定
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    //如果不bind, 这里的this是undefined, 因为回调用函数是系统调用的,不是某个对象调用的
    //console.log(this.__proto__ === Toggle.prototype)
    //console.log(this.constructor === Toggle.prototype.constructor)
    //打印分析一下原型链
    console.log(this)
    this.setState(state => ({
      isToggleOn: !state.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}
export default Toggle;

bind 改变this是永久绑定,绑定后不能更改

function bindDemo(){
        console.log(this)
    }
    var myObj = {
        sex: 'f'
    }
   var bin = bindDemo.bind(obj)
   bin()
   //bind是永久绑定的,再调用call/apply都不能改变this指向
   bin.call(myObj)
   bindDemo.call(myObj)

函数返回值中的this,除了return对象返回对应的对象外,其它都指向当前对象

function fn() {
          this.user = '前端食堂a'
          //return function(){}
          //return undefined
          return null
      }
      var a = new fn()
      console.log(a.user)

箭头函数中的this

var user = {
        name: 'zlw',
        callback1(){
            //callback1这个函数产生了新的作用域 create a new scope,谁调用就指向谁
            console.log(this)
        },
        callback2: () => {
            //callback2这里没有产生新作用域 did not create a new scope ,因为箭头函数没有this这个隐形参数,调用的是上一层作用域
            console.log(this)
        }
    }
    var obj = {name:'ttt',age:33}
    
    // call/apply/bind这些绑定本质是改变绑定对象

    // window.user.callback1()
    // user.callback1()
    // user.callback1.call(obj)
    // user.callback1.apply(obj)
    //apply,call都不能改变this指向
    //user.callback2()
    user.callback2.call(obj)
    //user.callback2.apply(obj)
    //user.callback1(() => {console.log(this)})

 再看一个例子

 var obj1 = {
      count: 10,
      
      /*
      doSomethingLater: function() {
          console.log(this)
          //since the arrow function was created within the "obj"
          //即箭头函数在哪里定义的,this就指向哪个作用域
        //   setTimeout(() => {
        //       this.count++
        //       console.log(this.count)
        //   }, 2000)

        //但凡创建一个函数就会创建新的相应的作用域链,这里的回调函数是系统调用的,指向window
        setTimeout(function() {
              console.log(this)
              this.count++
              console.log(this.count)
          }, 2000)
      }
      */
      //这里箭头函数也是在obj里定义的,为何不指向obj ?
      //这里因为obj定义的时候没有产生新的作用域,上例中定义了一个函数,产生了新作用域
      //这里箭头函数不能用来函数声明,可以用作函数表达式
      doSomethingLater: () => {
          //打印window
          console.log('i am ' + this)
        //   setTimeout(() => {
        //       console.log('you are ' + this)
        //   }, 2000);
        //打印window
         setTimeout(function(){
              console.log('you are ' + this)
          }, 2000);
      }
      
  }
  obj1.doSomethingLater()


call/apply与bind区别

 function bindDemo(){
        console.log(this)
    }
    var myObj = {
        sex: 'f'
    }
   var bin = bindDemo.bind(obj)
   bin()
   //bind是永久绑定的,再调用call/apply都不能改变this指向
   bin.call(myObj)
   bindDemo.call(myObj)
评论已关闭.