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 )
}
}
}
网友评论