this機(jī)制
javaScript這個(gè)迷人又令人困惑的混血兒昔汉,借鑒了多種編程語(yǔ)言的機(jī)制让网,這其中就包括就包括this機(jī)制。
this是什么辞友?
在javascript里面栅哀,this是一個(gè)特殊的對(duì)象,它不像其他編程語(yǔ)言那樣称龙,是存儲(chǔ)在實(shí)例中的值留拾,直接指向此實(shí)例。而是作為一個(gè)單獨(dú)的指針鲫尊,自動(dòng)定義于每一個(gè)函數(shù)域中痴柔,指向不同的位置,這也是為什么我們會(huì)將它搞混的原因马昨。
js中的this代表的是當(dāng)前行為的主體竞帽,js中上下文代表的是當(dāng)前行為執(zhí)行的環(huán)境。
為什么使用this
this為代碼復(fù)用提供了可能鸿捧,讓代碼變得更加簡(jiǎn)潔和復(fù)用屹篓。
this的5條規(guī)則
this到底綁定或者引用那個(gè)對(duì)象環(huán)境決定于函數(shù)被調(diào)用的地方。而函數(shù)的調(diào)用有著不同的方式匙奴,在不同的方式中調(diào)用決定this引用的是那個(gè)對(duì)象堆巧。
->我們一般只研究函數(shù)執(zhí)行的時(shí)候里面的this
->this是誰(shuí)和當(dāng)前的函數(shù)在哪執(zhí)行和在哪定義沒有半毛錢的關(guān)系
1)看函數(shù)執(zhí)行的時(shí)候,函數(shù)名之前是否有".",有的話"."前面是誰(shuí)this就是誰(shuí),沒有的話this就是window
oDiv.onclick=function(){
//匿名函數(shù)中的this->oDiv
fn();//fn函數(shù)中的this->window
};
[].slice(0);//->slice中的this是[]
[].__proto__.slice(0);//->slice中的this是Array.prototype
-->我們自己在數(shù)組原型中編寫的方法,一般情況下我們函數(shù)中的this就是當(dāng)前我們要操作的這個(gè)元素
Array.prototype.distinct=function(){
//this->我們當(dāng)前要操作的這個(gè)數(shù)組
};
[1,2,2,3,1,2,3,2,1].distinct();
2)自執(zhí)行函數(shù)中的this永遠(yuǎn)是window
(function(){ //this->window })();
~function(){ //this->window }();
window.setTimeout(function(){
//this->window
},10);
ary.sort(function(a,b){
//第一個(gè)匿名函數(shù)(參數(shù))在執(zhí)行的時(shí)候里面的 this->window
});
ary.forEach(function(){
//第一個(gè)匿名函數(shù)(參數(shù))在執(zhí)行的時(shí)候里面的 this->window
//但是如果context傳遞了值(第二個(gè)參數(shù)傳遞值了)那么這個(gè)方法中的this就是context
},context);
str.replace(reg,function(){
//this->window
});
3)給元素的某一個(gè)事件綁定方法,當(dāng)事件觸發(fā)的時(shí)候,方法中的this是當(dāng)前元素本身
//[DOM零級(jí)事件綁定]
oDiv.onclick=function(){
//this->oDiv
};
//[DOM二級(jí)事件綁定]
oDiv.addEventListener("click",function(){
//this->oDiv
},false);
//在IE6~8下使用attachEvent
oDiv.attachEvent("click",function(){
//this->window
});
4)在構(gòu)造函數(shù)模式中,我們的this.xxx=xxx中的this是當(dāng)前的類的一個(gè)實(shí)例
function Fn(){
this.x=100;//this->f x是給當(dāng)前實(shí)例f增加的私有的屬性
}
Fn.prototype.getX=function(){
console.log(this.x);
};
var f=new Fn;
f.getX();//getX中的this->f
f.__proto__.getX();//getX中的this->Fn.prototype
5)call和apply強(qiáng)制改變this的指向->以上所有的this情況在遇到call/apply的時(shí)候都不好使,都已強(qiáng)制改變的為主
obj.fn.call(1);//this->1
一般情況下,我們執(zhí)行call方法第一個(gè)傳遞的參數(shù)值是誰(shuí),那么fn中的this就是誰(shuí)
[在非嚴(yán)格模式下]
第一個(gè)參數(shù)沒有傳遞值、傳遞的是null泼菌、傳遞的是undefined fn中的this都是window
[嚴(yán)格模式下]
第一個(gè)參數(shù)傳遞的是誰(shuí)this就是誰(shuí),傳遞null/undefined,fn中的this都是對(duì)應(yīng)的null/undefined,不傳遞值默認(rèn)也是undefined
小結(jié)
默認(rèn)綁定全局變量
隱式調(diào)用
function fn(){
a=1;
console.log(this.a)
}
var obj = {
a=2,
fn:fn
};
obj.fn(); //2
//只看倒數(shù)第一個(gè)小數(shù)點(diǎn)·前的對(duì)象谍肤;
//即最后一個(gè)調(diào)用該函數(shù)的對(duì)象就是傳到該函數(shù)的上下文;
function fn(){
console.log(this.a)
}
var obj2 = {
a:42,
fn:fn
}
var obj1 = {
a:2,
obj2:obj2
}
obj1.obj2.fn() //42;
失去隱式綁定
function fn(){
cnsole.log(this.a)
}
obj1 = {
a:2,
fn:fn
};
var bar =obj1.fn;
var a = "全局變量"
bar() //全局變量
- 顯式綁定
即通過(guò)call/apply/bind給函數(shù)傳入this
- new實(shí)例綁定
你以為 你以為的 就是你以為的