美文网首页
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