this的指向问题

this 的指向问题
  第一种:指向调用者
    function a(){
      console.log(this)//Window
    }
    a() //每一个函数前面都会隐式的调用Window,所以相当于Window.a();

    var a = {
      b:'1',
      fn:function (){
        console.log(this.b)//1
      }
    }
    a.fn() //a调用了fn 所以this指向的是a;

  在举个特殊的例子作对比
    var a = {
      b:'1',
      fn:function(){
        console.log(this.a);//undefind
        console.log(this);//Window
      }
    }
    var j = a.fn();
    j()
  //在这里this永远指向他的调用者,但这里fn虽然被a调用了,但赋值给变量 j的时候没有执行所以最后的this是Window


  第二种:构造函数指向实例化的对象
    function a(){
      b:'1';
    }
    var c = new a;
    console.log(c.b);//1


  第三种:有返回值的this情况
    function a(){
      this.b = '1';
      return {}
    }
    var c = new a;
    console.log(c.b) //undefined

    function a(){
      this.b = '1';
      return function(){}
    }
    var c = new a;
    console.log(c.b) //undefined
    //如果返回的是对象,那么this指向的就是那个对象

    function a(){
      this.b = '1';
      return 1
    }
    var c = new a;
    console.log(c.b) // 1

    function a(){
      this.b = '1';
      return undefined
    }

    var c = new a;
    consoel.log(c.b) //1
    //如果返回的不是对象,那么this指向的还是实例化出的对象


  特殊的null
    null是对象但他并不会返回对象,而是返回实例化出来的对象
    function a(){
      this.b = '1';
      return null
    }
    var c = new a;
    console.log(c.b) //1

    原因,在js设计初期并没有null,null是之后添加的,为了不推翻以前的设 计思路就没有使this在构造函数中返回null他本身

 

  this 的指向问题2,call,apply和bind

    在上面我们有个特殊的函数
      var a = {
        b:'1'
        fn:function(){
          console.log(this.b) //undefined
          console.log(this) //Window
        }
      }
      var c = a.fn;
      c()
  我们发现因为函数执行问题,这里的this是指向Window的,可是我们如果需要使用这里的b,那么我们就需要用到,call,apply,bind这些改变this指向的方法。

    第一种:call()
      var a = {
        b:'1'
        fn:function(){
          console.log(this.b) //改变了this指向现在this指向的是a 输出 1
        }
      }
      var c = a.fn;
      c.call(a) //

      call() 的传参call(this,x,x,x)前面一个要改变的this后面跟参数
      var a = {
        b:'1'
        fn:function(x,xx){
          console.log(this.b) //1
          console.log(x,xx) //11,111
        }
      }
      var c = a.fn;
      c.call(a,11,111)

    第二种:apply()
      var a = {
        b:'1'
        fn:function(){
          console.log(this.b) //改变了this指向现在this指向的是a 输出 1

        }
      }
      var c = a.fn;
      c.apply(a)

      apply() 的传参call(this,[x,xx])前面一个要改变的this后面跟数组
      var a = {
         b:'1'
        fn:function(x,xx){
          console.log(this.b) //1
          console.log(x,xx) //11,111
         }
       }
       var c = a.fn;
      c.call(a,[x,xx])

    第三种:bind()

      var a = {
        b:'1'
        fn:function(){
          console.log(this.b) //1
        }
      }
      var c = a.fn;
      var d = c.bind(a) //bind()于call()apply()不同他返回的是一个新的函数所以要调用一下
      d()

      bind() 的传参
      var a = {
        b:'1'
        fn:function(x,xx,xxx){
          console.log(this.b) //1
          console.log(x,xx) //11,111
        }
      }
      var c = a.fn;
      var d = c.bind(a,11);
      d(111,1111) //他可以在bind里面传参也可以在调用时传参

   call(),apply(),bind()的区别
      call() 参数是this和任意数量的数
      apply() 参数是this和数组
      bind() 是返回一个新数组,需要在调用,参数可在bind()里传值,也可在调用时传参

      call(),apply()是改变上下文this指向并立即执行
      bind()方法是对应想什么时候调用什么时候调用,并且可以在的调用的时候添加参数

 

posted @ 2018-12-20 15:48  灵氛  阅读(125)  评论(0编辑  收藏  举报