我們?cè)趈s中主要研究的都是函數(shù)中的this
js中的this代表的是當(dāng)前行為執(zhí)行的主體
js中的context(上下文)代表的是當(dāng)前行為執(zhí)行的環(huán)境(區(qū)域)
this是誰和函數(shù)在哪定義的和在哪執(zhí)行的都沒有任何的關(guān)系
如何的區(qū)分 this
1.函數(shù)執(zhí)行,首先看函數(shù)名前面是否有 " . ",有的話" . "前面是誰this就是誰;沒有的話this就是window;
function fn(){
console.log(this)
}
var obj = { fn : fn };
fn(); // this -> window
obj.fn() // this -> obj
function sum(){
fn(); // this -> window
}
sum()
var oo = {
function sum(){
fn(); //this -> window
}
}
oo.sum();
2.自執(zhí)行函數(shù)中的this永遠(yuǎn)是window
3.給元素的某一個(gè)事件綁定方法,當(dāng)事件觸發(fā)的時(shí)候,執(zhí)行對(duì)應(yīng)的方法
<div id="div1">點(diǎn)擊</div>
<script>
function fn(){
console.log(this)
}
document.getElementById("div1").onClick = fn; // fn中的this是 #div1
document.getElementById("div1").onClick = function(){
fn(); // this -> window
}
</script>
預(yù)解釋/作用域/內(nèi)存/this綜合練習(xí)題
var num = 20;
var obj = {
num: 30,
fn: (function(num){
this.num *= 3;
num += 15;
var num = 45;
return function(){
this.num *= 4;
num += 20;
console.log(num);
}
})(num) // -> 把全局變量num的值20賦值給了自執(zhí)行函數(shù)的形參,而不是obj下的30,如果想是obj下的30,我們需要寫obj.num
};
var fn = obj.fn;
fn(); // -> 65
obj.fn(); // -> 85
console.log(window.num, obj.num); // -> 240, 120
練習(xí): 累加的投票器
<style type="text/css">
#btn{width: 240px;line-height: 1.8;background:#f1f1f1;font-size: 24px;text-align: center;margin: 200px auto;cursor: pointer;user-select: none;}
#spanNum{font-weight: 600;color: orange;}
</style>
<div id="btn">請(qǐng)投票: <span id="spanNum">0</span></div>
方案一: 利用全局作用域不銷毀的原理, 把需要累加的數(shù)字定義為全局的變量;
var oBtn = document.getElementById('btn'),
spanNum = document.getElementById('spanNum');
// 方案一
var count = 0
oBtn.onclick = function (){
count++;
spanNum.innerHTML = count;
} // 弊端: 在項(xiàng)目中為了防止全局變量之間的沖突,我們一般是禁止或者減少使用全局變量的
方案二: 自己形成一個(gè)不銷毀的私有作用域來保護(hù)需要累加的數(shù)字
// 方案二(1)
var oBtn = document.getElementById('btn'),
spanNum = document.getElementById('spanNum');
~function(){
var count = 0
oBtn.onclick = function (){
count++;
spanNum.innerHTML = count;
}
}() // 弊端: 有一個(gè)不銷毀的私有作用域,所以占內(nèi)存
// 方案二(2)
var oBtn = document.getElementById('btn'),
spanNum = document.getElementById('spanNum');
oBtn.onclick = (function(){
var count = 0
return function(){
count++;
spanNum.innerHTML = count;
}
})() // 弊端: 有一個(gè)不銷毀的私有作用域,所以占內(nèi)存
方案三: 利用innerHTML的方式處理: 每一次點(diǎn)擊的時(shí)候先到頁面中獲取最新的值,然后累加,最后把累加的結(jié)果重新放回去
// 方案三
var oBtn = document.getElementById('btn'),
spanNum = document.getElementById('spanNum');
oBtn.onclick = function(){
spanNum.innerHTML++;
} // 弊端: 每一次都需要把頁面中的內(nèi)容先轉(zhuǎn)換為字符串然后累加,
// 累加完再重新添加回去,當(dāng)重新添加的時(shí)候?yàn)g覽器都要重新渲染一次
方案四: 利用自定義屬性存儲(chǔ)(推薦)
oBtn.count = 0;
oBtn.onclick = function(){
sapnNum.innerHTML = ++this.count
}