JavaScript基础 this

this

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

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

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

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

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

冒泡里的this

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  数学对象

案例



    

注意事项:

 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指向

之前的案例可以写成:


    

兼容写法

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)