this
函數(shù)里面都能this, this指向是由函數(shù)執(zhí)行的方式來決定的
一命爬、函數(shù)自執(zhí)行this指向window;
function a(){
alert( this ); //彈出window
}
a();
二土匀、無論哪種形式的事件函數(shù)锦爵,函數(shù)內(nèi)部this指向都是觸發(fā)事件的對(duì)象舱殿;
document.onclick = a; ===>彈出document
冒泡里的this
<div id='box'></div>
var oBox = document.getElementById ( 'box' );
oBox.onclick = a; //這里點(diǎn)擊box的時(shí)候也會(huì)點(diǎn)擊document 所以會(huì)彈出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();
自執(zhí)行的this都是指向window
三、對(duì)象.屬性(有函數(shù)) 函數(shù)內(nèi)部this指向該函數(shù)
var oBox = document.getElementById ( 'box' );
oBox.a = function (){ //給對(duì)象屬性加函數(shù)
console.log(this); //指向?qū)ο蟊旧恚?}
oBox.a(); <===> (oBox.a)();
document.onclick = oBox.a; 指向document
改變this指向
call方法
1樟氢、在函數(shù)執(zhí)行階段使用冈绊,可以改變this指向;
2埠啃、.call(第一參數(shù)死宣,實(shí)參,實(shí)參霸妹,....) 第一個(gè)參數(shù)是改變this十电,后面的要傳的實(shí)參
3、都用 叹螟, 隔開
1、沒有傳參的時(shí)候
var oBox = document.getElementById( 'box' );
function a(){
console.log( this );
}
a(); //這里指向window;
現(xiàn)在要把this改為document
a.call(document); //打印document
a.call( oBox );//打印出box台盯;
2罢绽、有傳參的時(shí)候
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、有多個(gè)形參的時(shí)候
.call(改變this 静盅, x , y , z , i,......);// x y z i ...對(duì)應(yīng)的上面形參
4良价、其他數(shù)據(jù)類型this指向
function x( x ){
console.log( this );
}
x( 0 ); //這里指向Number;
x( 10 ); //這里指向Number;
x( '你好' ); //這里指向String;
x( true );//這里指向Boolean;
x( [] );//這里指向數(shù)組;
x( null )//這里指向window
x( undefined )//這里指向window
null和undefined里都是指向window
apply方法
1、在函數(shù)執(zhí)行階段使用蒿叠,可以改變this指向
2明垢、apply的第一個(gè)參數(shù)代表函數(shù) this 指向
3、apply的第二個(gè)參數(shù)是一個(gè)數(shù)組市咽,數(shù)組的第一位對(duì)應(yīng)原函數(shù)的第一個(gè)形參痊银,以此類推;
1沒有傳參的時(shí)候
function a(){
console.log( this );
}
a(); //指向window
a.apply( document )//指向document
a.apply( oBox )//指向oBox
有傳參的時(shí)候
function a( x , y ){
console.log( this );
}
a.apply( document , [ 10 , 20 ])//第一個(gè)改變this 第二是數(shù)組 數(shù)組里的第一位是對(duì)應(yīng)的第一個(gè)形參 第二位對(duì)應(yīng)第二形參 以此類推施绎;
這里this = document x = 10 ; y = 20 ;
4溯革、其他數(shù)據(jù)類型this指向
apply和call一樣,第一個(gè)參數(shù)unll 谷醉、undefined時(shí)致稀,this都是指向window
對(duì)象屬性函數(shù)里的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 數(shù)學(xué)對(duì)象
案例
<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';
}
====我們要利用傳參來改變寬高 這樣擴(kuò)展性好
function fn( x , y ){
console.log( this );
this.style.width = x + 'px';
this.style.height = y + 'px';
}
oBox.onclick = fn( 400 , 400 ); //這里不能這寫俱尼,加上括號(hào)函數(shù)馬上會(huì)自執(zhí)行===>這里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 (){ //放在函數(shù)里面點(diǎn)擊的時(shí)候才能執(zhí)行
fn( 400 , 400 ) //這里點(diǎn)擊后會(huì)自執(zhí)行 自執(zhí)行this都是window所以要改變this的指向
}
oWrap.onclick = function (){ //放在函數(shù)里面點(diǎn)擊的時(shí)候才能執(zhí)行
fn( 400 , 400 ) //這里點(diǎn)擊后會(huì)自執(zhí)行 自執(zhí)行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指向觸發(fā)函數(shù)本身
fn.call( a , 400 , 400 )
}
oWrap.onclick = function (){
var a = this; //這里this指向觸發(fā)函數(shù)本身
fn.call( a , 500 , 800) //改寫成這樣就可以隨便改值
}
</script>
</body>
注意事項(xiàng):
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不會(huì)被回收,占用內(nèi)存,用oBox不好
}
oWrap.onclick = function (){
fn.call( oWrap , 500 , 800) /這里也可以矛绘,閉包問題oBox不會(huì)被回收耍休,占用內(nèi)存,用oBox不好
}
用 apply 也可以
bind方法
1蔑歌、在函數(shù)定義的時(shí)候改變this的指向
2羹应、不會(huì)幫函數(shù)執(zhí)行,call apply會(huì)幫函數(shù)執(zhí)行
3次屠、不支持IE8及以下
call和apply
function a(){
console.log( this );
}
document.onclick = a.call( window );//===>還沒點(diǎn)擊就執(zhí)行了 call會(huì)幫函數(shù)執(zhí)行园匹;
bind
function a(){
console.log( this );
}
document.onclick = a.bind( window );//===>點(diǎn)擊的時(shí)候才會(huì)執(zhí)行 bind不會(huì)幫函數(shù)執(zhí)行
bind注意事項(xiàng)
1、定義一個(gè)函數(shù)的時(shí)候
function a(){
console.log( this );
}.bind( window ) //不能直接在這里設(shè)置bind,這里是在直接定義一個(gè)a的函數(shù)劫灶;
document.onclick = a;
要在這里寫
function a(){
console.log( this );
}
document.onclick = a.bind( window );
2裸违、匿名函數(shù)的時(shí)候
oBox.onclick = function (){
console.log( this );
}.bind( window );
匿名函數(shù)可以直接再后面定義
function fn( a ){
a();
}
fn(
function (){
console.log( this ); //彈出 數(shù)學(xué)對(duì)象
}.bind( Math )
)
這里把一個(gè)函數(shù)當(dāng)參數(shù)傳進(jìn)去,fn()執(zhí)行函數(shù)
不能在定義的時(shí)候改this本昏,當(dāng)函數(shù)執(zhí)行的時(shí)候才能改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);//這里不會(huì)產(chǎn)生閉包供汛,沒有函數(shù)套函數(shù)
oWrap.onclick = fn.bind( oWrap , 400 , 300);//這里不會(huì)產(chǎn)生閉包,沒有函數(shù)套函數(shù)
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是指向調(diào)用它的
//第一個(gè)arguments[0] 是this 現(xiàn)在要把參數(shù)切出來
var arg = [].slice.call( arguments , 1); //[].slice()利用數(shù)組來調(diào)用slice
// slice()里面有this 利用call改變要切割的對(duì)象
return function ( ) {
bindThid.apply( This , arg )
}
}
}