this
的第一次接觸是做一個(gè)父容器事件代理的DEMO,當(dāng)時(shí)還不會(huì)jquery;
<ul class="ct">
<li>內(nèi)容1</li>
<li>內(nèi)容2</li>
<li>內(nèi)容3</li>
</ul>
var ct=document.querySelector('.ct');
ct.addEventListener('click',function(e){
console.log(e.target.innerText);
});
第一次接觸this
,感覺這個(gè)太厲害了,就是誰調(diào)用就是誰;后來遇到這樣一個(gè)DEMO
function foo(){
console.log(this);
function foo2(){
console.log(this);
}
foo2();
}
foo();
我以為第一個(gè)結(jié)果是window
,第二個(gè)結(jié)果是foo2
,結(jié)果控制臺(tái)的輸入狠狠的打臉了!
輸出結(jié)果
當(dāng)時(shí)我就懵逼了,因?yàn)閺?元素之力"的世界來,"零一世界"的運(yùn)作原理還知之甚少,后來經(jīng)過別人點(diǎn)撥,這個(gè)是由于堆棧,是計(jì)算機(jī)的一個(gè)原理;
后來我想想,應(yīng)該是我在全局環(huán)境下調(diào)用了foo(),然后window將整個(gè)foo()給推入了堆棧,第一個(gè)輸出為window理所應(yīng)當(dāng),那么foo(2)也是被window給推進(jìn)堆棧的,"幕后黑手"也是window,這樣應(yīng)該就解釋了,這個(gè)demo中第二個(gè)輸出的結(jié)果還是window,雖然是函數(shù)內(nèi)部嵌套函數(shù),但this依舊指向了window;
手賤的我又看到了call和apply,這種切換this的手段
var obj1 = {
name:'ran',
fn:function(){
console.log(this);
}
};
obj1.fn();
var fn2 = obj1.fn;
fn2();
fn2.call(obj1);
為什么會(huì)這樣呢?
- 第一個(gè):obj.fn()是obj去調(diào)用fn的,當(dāng)然第一個(gè)是他,這個(gè)沒有什么異議;
- 第二個(gè)陷阱就來了,在全局環(huán)境下聲明fn2=obj.fn;再去執(zhí)行fn2,這個(gè)時(shí)候相當(dāng)于再全局環(huán)境下執(zhí)行
function(){
console.log(this);
}
一開始,我也犯了迷糊,明明fn在obj之內(nèi),怎么又指向全局了,后來我想明白了,這只是一個(gè)賦值,讓fn2擁有這個(gè)函數(shù)罷了,相當(dāng)于obj是一個(gè)銀行,fn就是100快,現(xiàn)在銀行外面的fn2從銀行取出一個(gè)100快,總不能因?yàn)槎际?00快,就說fn2的錢還是銀行的吧;
- 第三個(gè):用call切換了,函數(shù)的作用域,打到了切換this的指向,本來fn2的作用域是全局,this是指向window的,結(jié)果被call切換到了obj里面,自然把黑鍋又給了obj,那么這個(gè)this就指向了obj,最后輸出也是obj,而不是window;