美文网首页
JavaScript基础 this

JavaScript基础 this

作者: 0说 | 来源:发表于2018-01-30 11:31 被阅读0次

    this

    函数里面都能this, this指向是由函数执行的方式来决定的

    一、函数自执行this指向window;

    function a(){
          alert( this ); //弹出window
    }
    a();
    

    二、无论哪种形式的事件函数,函数内部this指向都是触发事件的对象;

    document.onclick = a; ===>弹出document
    

    冒泡里的this

    <div id='box'></div>
    var oBox = document.getElementById ( 'box' );
    oBox.onclick = a;      //这里点击box的时候也会点击document  所以会弹出2次;
    document.onclick = a;    div    document
    

    特殊情况:

    一、
    var a = function (){
        console.log( this ); ====>指向window;
    };
    a();
    
    二、
    var a = function (){
        console.log( this ); ====>指向window;
    };
    function b(){
      a();
    }
    b();  
    

    自执行的this都是指向window

    三、对象.属性(有函数) 函数内部this指向该函数

    var oBox = document.getElementById ( 'box' );
    oBox.a = function (){ //给对象属性加函数
        console.log(this); //指向对象本身;
    }
    oBox.a(); <===>  (oBox.a)();
    
    document.onclick = oBox.a; 指向document
    

    改变this指向

    call方法
    1、在函数执行阶段使用,可以改变this指向;
    2、.call(第一参数,实参,实参,....) 第一个参数是改变this,后面的要传的实参
    3、都用 , 隔开

    1、没有传参的时候

    var oBox = document.getElementById( 'box' );
    function a(){
        console.log( this );
    }
    a(); //这里指向window;
    现在要把this改为document
    a.call(document); //打印document
    a.call( oBox );//打印出box;
    

    2、有传参的时候

    function a( x , y ){
        console.log( x );
        console.log( y );
        console.log( this );
    }
    a( 200 , 200 ) //这里this指向window
    a.call( document , 200 , 200 ) //这里this指向document
    

    3、有多个形参的时候

    .call(改变this , x , y , z , i,......);// x y z i ...对应的上面形参
    

    4、其他数据类型this指向

    function x( x ){
        console.log( this );
    }
    x( 0 ); //这里指向Number;
    x( 10 ); //这里指向Number;
    
    x( '你好' ); //这里指向String;
    x( true );//这里指向Boolean;
    x( [] );//这里指向数组;
    
    x( null )//这里指向window
    x( undefined )//这里指向window
    
    null和undefined里都是指向window
    

    apply方法
    1、在函数执行阶段使用,可以改变this指向
    2、apply的第一个参数代表函数 this 指向
    3、apply的第二个参数是一个数组,数组的第一位对应原函数的第一个形参,以此类推;

    1没有传参的时候

    function a(){
          console.log( this );
    }
    a(); //指向window
    a.apply( document )//指向document
    a.apply( oBox )//指向oBox
    

    有传参的时候

    function a( x , y ){
          console.log( this );
    }
    a.apply( document , [ 10 , 20 ])//第一个改变this  第二是数组    数组里的第一位是对应的第一个形参   第二位对应第二形参   以此类推;
      这里this = document  x = 10 ; y = 20 ;
    

    4、其他数据类型this指向
    apply和call一样,第一个参数unll 、undefined时,this都是指向window

    对象属性函数里的this

    var oBox = document.getElementById( 'box' );
    oBox.a = function (){
        console.log( this );
    }
    oBox.a(); ==>这里指向oBox
    

    改变this的指向

    oBox.a.call( document ) ==>指向document
    oBox.a.call( Math ) ==>指向Math  数学对象
    

    案例

    <style>
        div{
            width: 200px;
            height: 200px;
            background: #000;
            transition: all 0.5s;
        }
        div#wrap{
            background: red;
        }
    </style>
    <body>
        <div id='box'></div>
        <div id="wrap"></div>
        <script>
            var oBox = document.getElementById( 'box' );
            var oWrap = document.getElementById( 'wrap' );
    
            oBox.onclick = function (){
                this.style.width = '400px';
                this.style.height = '400px';
            }
            oWrap.onclick = function (){
                this.style.width = '400px';
                this.style.height = '400px';
            }
    
    ====可以写成
          oBox.onclick = fn;
          oWrap.onclick = fn;
    
          function fn(){
              this.style.width = '400px';
              this.style.height = '400px';
          }
    ====我们要利用传参来改变宽高 这样扩展性好
          function fn( x , y ){
              console.log( this );
              this.style.width = x + 'px';
              this.style.height = y + 'px';
          }
          oBox.onclick = fn( 400 , 400 );  //这里不能这写,加上括号函数马上会自执行===>这里this指向window
          oWrap.onclick = fn;
    
    ====改写成
          function fn( x , y ){
              console.log( this );
              this.style.width = x + 'px';
              this.style.height = y + 'px';
          }
          oBox.onclick = function (){ //放在函数里面点击的时候才能执行
            fn( 400 , 400 ) //这里点击后会自执行  自执行this都是window所以要改变this的指向
          }
          oWrap.onclick = function (){ //放在函数里面点击的时候才能执行
            fn( 400 , 400 ) //这里点击后会自执行  自执行this都是window所以要改变this的指向
          }
    
    ====改变this的指向
          function fn( x , y ){
              console.log( this );
              this.style.width = x + 'px';
              this.style.height = y + 'px';
          }
          oBox.onclick = function (){ 
            var a = this;//这里this指向触发函数本身
            fn.call( a , 400 , 400 ) 
          }
          oWrap.onclick = function (){ 
            var a = this; //这里this指向触发函数本身
            fn.call( a , 500 , 800)  //改写成这样就可以随便改值
          }
        </script>
    </body>
    

    注意事项:

     function fn( x , y ){
              console.log( this );
              this.style.width = x + 'px';
              this.style.height = y + 'px';
          }
          oBox.onclick = function (){ 
            fn.call(oBox , 400 , 400 ) //这里也可以,闭包问题oBox不会被回收,占用内存,用oBox不好
          }
          oWrap.onclick = function (){ 
            fn.call( oWrap , 500 , 800) /这里也可以,闭包问题oBox不会被回收,占用内存,用oBox不好
          }
    
    
    用 apply 也可以
    

    bind方法
    1、在函数定义的时候改变this的指向
    2、不会帮函数执行,call apply会帮函数执行
    3、不支持IE8及以下

    call和apply 
    function a(){
      console.log( this );
    }
    document.onclick = a.call( window );//===>还没点击就执行了  call会帮函数执行;
    
    
    bind
    function a(){
      console.log( this );
    }
    document.onclick = a.bind( window );//===>点击的时候才会执行  bind不会帮函数执行
    

    bind注意事项

    1、定义一个函数的时候

    function a(){
      console.log( this );
    }.bind( window ) //不能直接在这里设置bind,这里是在直接定义一个a的函数;
    document.onclick = a;
    
    要在这里写
    function a(){
      console.log( this );
    }
    document.onclick = a.bind( window );
    

    2、匿名函数的时候

    oBox.onclick = function (){
        console.log( this );
    }.bind( window );
    匿名函数可以直接再后面定义
    
    function fn( a ){
        a();
    }
    fn(
          function (){
             console.log( this ); //弹出 数学对象 
          }.bind( Math )
    )
    这里把一个函数当参数传进去,fn()执行函数
    

    不能在定义的时候改this,当函数执行的时候才能改this指向

    之前的案例可以写成:

    <body>
        <div id='box'></div>
        <div id="wrap"></div>
        <script>
            var oBox = document.getElementById( 'box' );
            var oWrap = document.getElementById( 'wrap' );
            oBox.onclick = fn.bind( oBox , 500 , 500);//这里不会产生闭包,没有函数套函数
            oWrap.onclick = fn.bind( oWrap , 400 , 300);//这里不会产生闭包,没有函数套函数
            function fn( x , y ){
                console.log(this);
                this.style.width = x + 'px';
                this.style.height = y + 'px';
            }
        </script>
    

    兼容写法

    if( !Function.prototype.bind ){
                Function.prototype.bind = function ( This ) {
                    var bindThid = this;  //这里的this是指向调用它的
                    
                    //第一个arguments[0] 是this 现在要把参数切出来
                    var arg = [].slice.call( arguments , 1);  //[].slice()利用数组来调用slice  
                                                                // slice()里面有this 利用call改变要切割的对象
                    return function (  ) {
                        bindThid.apply( This , arg )
                    }
                }
            }
    

    相关文章

      网友评论

          本文标题:JavaScript基础 this

          本文链接:https://www.haomeiwen.com/subject/brnqzxtx.html