~~~
/*
* [閉包]
* =>函數執形成一個私有的作用域,保護里面的私有變量不受外界的干擾,
* 這種保護機制稱之為“閉包”
*
* =>市面上的開發者認為的閉包是:形成一個不銷毀的私有作用域(私有棧內存)才是閉包
*/
/*
//=>閉包:柯理化函數
function fn() {
return function () {
}
}
var f = fn();
*/
/*
//=>閉包:惰性函數
var utils = (function () {
return {
}
})();
*/
//=>閉包項目實戰應用
//==>真實項目中為了保證JS的性能(堆棧內存的性能優化),
應該盡可能的減少閉包的使用(不銷毀的堆棧內存是耗性能的)
//1.閉包具有“保護”作用:保護私有變量不受外界的干擾
//> 在真實項目中,尤其是團隊協作開發的時候,應當盡可能的減少全局變量的使用,
以防止相互之前的沖突(“全局變量污染”),
那么此時我們完全可以把自己這一部分內容封裝到一個閉包中,讓全局變量轉換為私有變量
/*
(function () {
var n = 12;
function fn() {
}
//...
})();
*/
//> 不僅如此,我們封裝類庫插件的時候,也會把自己的程序都存放到閉包中保護起來,防止和用戶的程序沖突,但是我們又需要暴露一些方法給客戶使用,這樣我們如何處理呢?
//1.JQ這種方式:把需要暴露的方法拋到全局
/*
(function () {
function jQuery() {
//...
}
//...
window.jQuery = window.$ = jQuery;//=>把需要供外面使用的方法,通過給WIN設置屬性的方式暴露出去
})();
// jQuery();
// $();
*/
//2.Zepto這種方式:基于RETURN把需要共外面使用的方法暴露出去
/*
var Zepto=(function () {
//...
return {
xxx:function () {
}
};
})();
Zepto.xxx();
*/
//2.閉包具有“保存”作用:形成不銷毀的棧內存,把一些值保存下來,方便后面的調取使用
~~~
~~~
var oTab = document.getElementById('tab'),
tabList = oTab.getElementsByTagName('li'),
divList = oTab.getElementsByTagName('div');
function changeTab(curIndex) {
for (var i = 0; i < tabList.length; i++) {
tabList[i].className = divList[i].className = '';
}
//=>curIndex:記錄的是當前點擊LI的索引
tabList[curIndex].className = 'active';
divList[curIndex].className = 'active';
}
/*
for (var i = 0; i < tabList.length; i++) {
tabList[i].onclick = function () {
changeTab(i);
//=>執行方法,形成一個私有的棧內存,遇到變量I,I不是私有變量,向上一級作用域查找(上級作用域WINDOW)
//=>所有的事件綁定都是異步編程(同步編程:一件事一件事的做,當前這件事沒完成,
下一個任務不能處理 / 異步編程:當前這件事件沒有徹底完成,不在等待,繼續執行下面的任務),
綁定事件后,不需要等待執行,繼續執行下一個循環任務,所以當我們點擊執行方法的時候,
循環早已結束(讓全局的I等于循環最后的結果3)
}
}
*/
//=>解決方案:自定義屬性
/*for (var i = 0; i < tabList.length; i++) {
tabList[i].myIndex = i;
tabList[i].onclick = function () {
changeTab(this.myIndex);
//=>THIS:給當前元素的某個事件綁定方法,當事件觸發,方法執行的時候,方法中的THIS是當前操作的元素對象
}
}*/
//=>解決方案:閉包,閉包具有保存的作用
/*for (var i = 0; i < tabList.length; i++) {
tabList[i].onclick = (function (n) {
//=>讓自執行函數執行,把執行的返回值(RETURN)賦值給ON-CLICK
(此處ON-CLICK綁定的是返回的小函數,點擊的時候執行的是rerurn小函數),
自執行函數在給事件賦值的時候就已經執行了
var i = n;
return function () {
changeTab(i);//=>上級作用域:自執行函數形成的作用域
}
})(i);
}*/
/*
* i=0 第一次循環
* tabList[0].onclick = (function(n){
* //=>自執行函數執行形成一個私有作用域(不釋放:返回的函數對應的堆地址被外面的事件占用了)
* //1.形參賦值 n=0
* //2.變量提升 var i;
* var i=n; //=>i=0
* return function(){//=>點擊的時候執行的是小函數
* changeTab(i);
* }
* })(i);//=>把本次全局I(0)當做實參傳遞給形參n
*
* i=1 第二次循環
* tabList[1].onclick = (function(n){
* var i=n; //=>i=1
* return function(){
* changeTab(i);
* }
* })(1);
*
* ...
*
* 總結:循環三次,形成三個不銷毀的私有作用域(自執行函數執行),
* 而每一個不銷毀的棧內存中都存儲了一個私有變量I,
* 而這個值分別是每一次執行傳遞進來的全局I的值
* (也就是:第一個不銷毀的作用域存儲的是0,第二個是1,第三個是2);
* 當點擊的時候,執行返回的小函數,遇到變量I,
* 向它自己的上級作用域查找,找到的I值分別是:0/1/2,達到了我們想要的效果;
*/
~~~
~~~
/*for (var i = 0; i < tabList.length; i++) {
/!*原理都是形成三個不銷毀的私有作用域,分別存儲需要的索引值*!/
(function (n) {
tabList[n].onclick = function () {
changeTab(n);
}
})(i);
}*/
//=>解決方案:基于ES6解決
for (let i = 0; i < tabList.length; i++) {
tabList[i].onclick = function () {
changeTab(i);
}
}
//=>基于ES6中的let來創建變量,是存在塊級作用域的(類似于私有作用域)
//作用域:(棧內存)
//1.全局作用域
//2.私有作用域(函數執行)
//3.塊級作用域(一般用大括號包起來的都是塊級作用域,前提是ES6語法規范)
/*
{
let a = 12;
console.log(a);//=>12
}
console.log(a);//=>Uncaught ReferenceError: a is not defined
*/
/*let a = 100;
{
let a = 100;
{
{
console.log(a);//=>100
}
}
}
*/
/*if (1 === 1) {
//=>判斷體也是塊級作用域
let a = 12;
}
console.log(a);//=>Uncaught ReferenceError: a is not defined*/
/*for (let i = 0; i < 5; i++) {
//=>循環體也是塊級作用域,初始值設置的變量是當前本次塊級作用域中的變量
(形成了五個單獨的塊級作用域,每個塊級作用域中都有一個私有變量I,變量值就是每一次循環I的值)
}
console.log(i);//=>Uncaught ReferenceError: i is not defined*/
// var obj={};//=>對象的大括號不是塊級作用域
~~~

在傳統語法中,能形成作用域的,只有全局和函數
- 1.變量提升、閉包、THIS、OOP
- 0002.NODE安裝及一些基礎概念
- 0003.常用的DOS命令
- 0004.基于npm包管理器下載所需資源
- 0005.簡單操作一遍gitHub
- 0006.集中式vs分布式版本控制系統
- 0007.簡述git安裝
- 0008.基于git創建一個空倉庫
- git-svn區別
- 0009.git的工作流程
- 0010.完成本地git倉庫個遠程gitHub倉庫的信息同步
- 0011.JS數據渲染機制及堆棧內存
- 0012.變量提升機制
- 0013.帶VAR和不帶的區別
- 0014.作用域鏈的一些擴展
- 0015.變量提升的一些細節問題(關于條件判斷下的處理)
- 0016.條件判斷下的變量提升到底有多坑
- 0017.變量提升機制下重名的處理
- 0018.ES6中的LET不存在變量提升
- 0019.JS中的暫時性死區問題
- 0020.區分私有變量和全局變量
- 0021.有關私有變量和作用域鏈的練習題
- 0022.上級作用域的查找
- 0023.閉包及堆棧內存釋放
- 0024.閉包作用之保護
- 0026.單例設計模式的理論模型
- 0027.強化高級單例模式理論模型
- 0028.實戰項目中的模塊化
- 0029.沒有什么實際意義的工廠模式
- 0030.JS是基于面向對象開發設計的語言
- 0031.創建值的兩種方式以及區別
- 0032.構造函數執行的機制
- 0033.構造函數中的一些細節問題
- 0034.原型鏈和原型鏈的查找機制
- 0045.練習題講解[19]-關于原型重定向問題綜合練習
- 0035.練習題講解[01-05]
- 0036.練習題講解[06~08]-JS中的嚴格模式和ARG的映射機制
- 0037.課件3&練習題講解[09]-邏輯或和邏輯與
- 0038.課件4&練習題講解[10]-有關堆棧內存釋放
- 0039.課件5&練習題講解[11~13]
- 0040.課件6&練習題講解[14]-堆棧內存和this混合應用題
- 0041.課件7&練習題講解[15]-構造函數和原型鏈的運行機制
- 0042.課件8&練習題講解[16]-基于閉包解決循環綁定
- 0043.課件9&練習題講解[17]-有關this的兩道面試題
- 0044.課件10&練習題講解[18]-關于原型重定向問題
- 0045.課件11&練習題講解[19]-關于原型重定向問題綜合練習
- 0046.課件12&練習題講解[20]-數組去重引發的基于內置類原型擴展方法,并且實現鏈式調用
- 0047.課件13&練習題講解[其余隨性題]-閉包和團隊協作開發
- 0049.課件1&LESS學習-如何編譯less
- 0050.課件2&LESS學習-less中最常用的一些基礎語法
- 總結
- 數組常用方法
- 2.原型深入、THIS、商城排序、正則
- 0051.原型深入1-函數的三種角色
- 0052.原型深入2-基于阿里的面試題理解函數的三種角色
- 0053.原型深入3-原型鏈機制最終版(Function)
- 0054.原型深入4-深入理解原型和CALL
- 0055.原型深入5-call、apply、bind三者的區別
- 0056.原型深入6-基于APPLY獲取數組中的最大值
- 0057.數組和對象的解構賦值
- 0058.剩余和展開運算符
- 0059.把類數組轉換為數組
- 0060.原型深入8-基于ES6的方式把類數組轉換為數組
- 0061.ES6-箭頭函數
- 0062.課件1&商城排序1-基于AJAX獲取數據(不講AJAX)
- 0063.課件2&商城排序2-把獲取的JSON字符串轉換為對象
- 0064.課件3&商城排序3-基于ES6模板字符串完成數據綁定
- 0065.課件4&商城排序4-按照價格升序排序
- 0066.課件5&商城排序5-簡述DOM映射機制
- 0067.課件6&商城排序6-按照價格升降序切換
- 0068.課件7&商城排序7-實現多列升降序切換
- 0069.課件8&商城排序8-解決多列切換中的一點BUG
- 0070.課件9&商城排序9-如何學習和練習項目案例
- 0071.課件10&復習商城排序1-基于LESS實現樣式
- 0072.課件11&復習商城排序2-高級單例模式框架結構
- 0073.課件12&復習商城排序3-數據獲取和綁定
- 0074.課件13&復習商城排序4-學習DOM映射和告別DOM映射
- 0075.課件14&復習商城排序5-完成事件綁定的邏輯
- 0076.課件15&復習商城排序6-由數據綁定引發的DOM性能優化
- 0077.課件1&正則基礎概念和常用的元字符梳理
- 0078.課件2&中括號的一點特殊細節
- 0079.課件3&分組的三個作用
- 0080.課件4&常用的正則表達式
- 0081.課件5&正則捕獲的懶惰性和解決方案
- 0082.課件6&正則捕獲的貪婪性和分組捕獲
- 0083.課件7&更多的捕獲方式(REPLACE)
- 0084.課件8&處理時間字符串格式化
- 3.Dom盒子模型、JQ
- 0086.課件1&考試題講解-第一次考試題[01~03]
- 0087.課件2&考試題講解-第一次考試題[04]
- 0088.課件3&考試題講解-第一次考試題[05]
- 0089.課件4&考試題講解-第一次考試題[06~08]
- 0090.課件5&考試題講解-第二次考試題[01~05]
- 延時打印-無視頻
- 0091.課件1&DOM盒子模型1-復習常用的DOM操作屬性和方法
- 0092.課件2&DOM盒子模型2-JS盒子模型屬性第一部分
- 0093.課件3&DOM盒子模型3-獲取元素的具體樣式
- 4. 前三周綜合復習
- 0112.課件1&ES6新語法和DOM回流
- 0113.課件2&關于面向對象的理解
- 0114.課件3&關于THIS匯總
- 0115.課件4&作用域鏈和原型鏈
- 0116.課件5&數組去重
- 0117.課件6&遞歸算法和數組扁平化
- 0119.課件8&ES6中的類及繼承
- 0120.課件9&正則的一點應用
- 0121.課件10&關于對閉包的理解
- 0122.課件11&閉包、THIS、面向對象綜合練習題
- 0123.課件12&復雜一些的正則
- 0124.課件13&拿正則搞各種需求
- 0125.課件14&一些雜七雜八的題
- 0126.課件15&圖片延遲加載
- 0127.課件16&柯理化函數編程思想
- 5.定時器、異步、動畫庫、輪播
- 0129.課件1&定時器基礎知識
- 0130.課件2&JS中的同步異步編程核心原理
- 0131.課件3&初識Promise
- 0135.課件7&回調函數原理和實戰
- NODE和PROMISE-34
- 024-[PROMISR A+]-復習PROMISR的使用
- 022-重點***[專題匯總]-JS中的同步異步(宏任務和微任務)
- 6.事件、事件委托、發布訂閱
- 1.事件和事件委托
- 149.課件1&事件的理論基礎
- 150.課件2&事件對象中常用的屬性
- 151.課件3&事件對象的兼容問題
- 152.課件4&默認行為及阻止
- 153.課件5&事件傳播機制(很重要)
- 158.課件10&事件委托
- 161.課件13&基于事件委托實現無限級折疊菜單
- 169.課件8&[拖拽]擴展柯理化函數編程思想
- 2.DOM事件綁定、發布訂閱
- 162.課件1&DOM0和DOM2的運行機制(事件池機制)
- 163.課件2&DOM2事件綁定的兼容問題
- 7.移動端開發
- 8.AJAX
- 226.課件14&14-基于PROMISE解決回調地獄問題
- 9.AXIOS視頻
- node和promise
- 22-[專題匯總]-JS中的同步異步(宏任務和微任務)
- REACT