閉包:
簡單來說就是將內(nèi)容封閉起來,外界無法訪問.
閉包技術(shù):
- 作用域規(guī)則:內(nèi)層的作用域可以訪問外層的作用域,但是反過來不行.
- 有的時候,我們確實需要訪問一個封閉空間中的數(shù)據(jù)源(外層作用域--->內(nèi)層作用域中的數(shù)據(jù)).
- 就是提供一種間接訪問封閉空間中私有數(shù)據(jù)的方法.
訪問數(shù)據(jù):
- 直接返回 return
- 閉包 對直接返回數(shù)據(jù)進行包裝(函數(shù))
閉包的作用
提供了一種間接訪問函數(shù)封閉空間中數(shù)據(jù)的方法.
- 訪問函數(shù)內(nèi)部的變量只能通過指定的接口
- 對變量的修改設(shè)置操作會更安全,我們可以在設(shè)置數(shù)據(jù)之前對數(shù)據(jù)進行校驗
- 延長變量的生命周期
當(dāng)然你可能有疑問為什么我們要使用閉包?那么接下來我們看看實例!
閉包的獲取和設(shè)置數(shù)據(jù)基本寫法:
function foo(){
var name = "張三";
var age = 18;
return {
getName:function(){
return name;
},
getAge:function(){
return age;
},
setName:function(nameValue){
name = nameValue;
},
setAge:function(ageValue) {
age = ageValue;
}
}
}
var func = foo();
console.log(func.getName());
func.setName("張校長");
console.log(func.getName());
func.setAge(20);
console.log(func.getAge());
setTimeOut中閉包的執(zhí)行
for (var i = 0; i <10; i++) {
//demo1
setTimeout(function(){
console.log(i);
},1000);
//demo2
(function(j){
setTimeout(function(){
console.log(j);
},0);
})(i);
//demo3
setTimeout((function(j){
return function (){
console.log(j);
}
})(i),0);
//demo1、demo2這兩種方法都是可以的
}
結(jié)果:demo1打印了10個10;
demo2打印0~9
demo3打印0~9
js任務(wù)執(zhí)行順序
01 渲染任務(wù)
02 代碼中的主要任務(wù)
03 事件型的任務(wù)(點擊事件|定時器事件)
這就是為什么我們要使用閉包的原因,當(dāng)直接在**for循環(huán)**中使用**定時器**的時候,由于**js任務(wù)執(zhí)行順序,for循環(huán)作為主要任務(wù)先執(zhí)行,而定時器作為事件型的任務(wù)后執(zhí)行**,所以打印了10個10,而閉包解決了這個問題,使得在for循環(huán)的同時將值傳遞過來.
提到執(zhí)行順序不得不說的就是**線程**:
**js本身是單線程的**
- 進程:進程指的是系統(tǒng)中正在運行的一個應(yīng)用程序. 工廠(車間)
- 線程:是進程中真正執(zhí)行任務(wù)的單元. 工人(線程)
- 串行執(zhí)行:一條線程在執(zhí)行任務(wù)的時候,按照固定的順序一個接著一個的執(zhí)行.
- 多線程:進程中可以擁有多條線程,多條線程一起執(zhí)行任務(wù)效率會更高.
- 并發(fā)執(zhí)行:多條線程一起來執(zhí)行多個任務(wù),感覺同一時間有多個任務(wù)在執(zhí)行.
舉個例子:比如完成某個人物如果一個人完成需要2天,這是單線程;二多線程就是給這個任務(wù)再加一個人,相當(dāng)于加了一條線程,這時候只需要1天就能完成任務(wù)
點擊事件也是如此:
//01 得到頁面中所有的div
var divs = document.getElementsByTagName("div");
//02 遍歷標(biāo)簽數(shù)組
// for (var i = 0; i < divs.length; i++) {
// (function(a){
// divs[a].onclick = function(){
// alert("我是第" + a + "標(biāo)簽");
// }
// })(i)
// }
for (var i = 0; i < divs.length; i++) {
divs[i].onclick = (function(a){
return function(){
alert("我是第" + a + "標(biāo)簽");
}
})(i)
}
志向和熱愛是偉大行為的雙翼。 —— 歌德