// 棧內(nèi)存:作用域
????1.提供一個供js代碼自上而下執(zhí)行的環(huán)境(代碼都是在棧中執(zhí)行的)
????2.由于基本數(shù)據(jù)類型比較簡單柠衍,他們都是直接在棧內(nèi)存中開辟了一個位置洋满,把值直接存儲起來
?????????=》當(dāng)棧內(nèi)存被銷毀,存儲的那些基本值也都被銷毀了
// 堆內(nèi)存:引用值對應(yīng)的空間
????1.存儲引用類型值得(對象:鍵值對 函數(shù):代碼字符串)
????????=》當(dāng)前堆內(nèi)存釋放被銷毀珍坊,那么這個引用值徹底沒了
????????=》堆內(nèi)存得釋放:當(dāng)堆內(nèi)存沒有被任何的變量或者其他東西所占用牺勾,瀏覽器會在空閑的時候,自主的進行內(nèi)存回收,把所有不被占用的堆內(nèi)存銷毀掉(谷歌瀏覽器)
? ? ? ? =》IE瀏覽器(計數(shù)--內(nèi)存泄漏)
????????xxx = null通過空對象指針null可以讓原始變量(或者其他東西)誰都不指向阅悍,那么原有被占用的堆內(nèi)存就沒有被其他東西占用了甲雅,瀏覽器被銷毀它。
### 變量提升
/*
????* 變量提升:
????*? -> 當(dāng)棧內(nèi)存(作用域)形成回还,JS代碼自上而下執(zhí)行之前,瀏覽器首先會把所有的帶“VAR(聲明)”/“function(定義)” 關(guān)鍵字的提前“聲明”或者“定義”叹洲,這種預(yù)先處理機制稱之為“變量提升”
????*
????* -> 聲明(declare): var a / function sum (默認值undefined)
????* -> 定義(defined): a=12 (定義其實就是賦值操作)
????*
????* 【變量提升階段】
? ? *? ? ?=》帶“VAR”的只聲明未定義
????*? ? ?=》帶“FUNCTION”的聲明和賦值都完成了
????*
????* ????=》 變量提升只發(fā)生在當(dāng)前作用域(例如:開始加載頁面的時候只對全局作用域下的進行提升柠硕,因為此時的函數(shù)中存儲的都是字符串而已)
????*
????*? ?=》 在全局作用域下聲明的函數(shù)或者變量是“全局變量”,同理,在私有作用域下聲明的變量是“私有變量”[帶VAR/FUNCTION的才是聲明]
????*
????*? ?=>瀏覽器很懶蝗柔,做過的事情不會重復(fù)執(zhí)行第二遍闻葵,也就是當(dāng)代碼執(zhí)行遇到創(chuàng)建函數(shù)這部分代碼后,直接跳過即可(因為在提升階段就已經(jīng)完成函數(shù)的賦值操作了)
????*
*/
console.log(a);? ? //undefined,說明a已經(jīng)存在
var a = 12;
function sum(){
????var total = null;
????for(var i=0;i<arguments.length;i++){
????????var item = arguments[i];
????????item=paeseFloat(item);
????????isNaN(item) ? total+=item:null;
????}
????return total;
}
console.log(sum(12,23,'34','AA'))
### 帶VAR和不加VAR的區(qū)別
// => 在全局作用域下聲明一個變量癣丧,也相當(dāng)于給WINDOW全局對象設(shè)置了一個屬性槽畔,變量的值就是屬性值(私有作用域中聲明的私有變量和WINDOW沒啥關(guān)系)
console.log(a); //=>undefined
console.log(window.a) // => undefined
console.log('a' in window)??
// =>TRUE 在變量提升階段,在全局作用域中聲明了一個變量A胁编,此時就已經(jīng)把A當(dāng)作屬性賦值給window了厢钧,只不過此時還沒有給A賦值,默認UNDEFINED?嬉橙。in:檢測某個屬性是否隸屬于這個對象
var a = 12;? ? //=》全局屬性修改坏快,window的屬性值也跟著修改
console.log(a); // =>window的一個屬性名A 12
a = 13;
console.log(window.a);? //13
window.a = 14;
console.log(a)? ? ? ? ? //14
// => 全局變量和WINDOW中的屬性存在“映射機制”
### in的操作(判斷某個對象中是否有某個屬性)
var obj = {name:undefined};
obj.name ????????????????????// undefined
obj.age????????????????? ????// undefined
console.log('name' in obj)? // true
console.log('age' in obj) // false
### 不帶VAR
// => 不加VAR的本質(zhì)是WINDOW的屬性,不是變量
console.log(a)? ? ? ? // a is not defined
console.log(window.a) //=>undefined
console.log('a' in window)? //=> false
a = 12; //=>window.a=12? ?a=12相等于window.a=12
console.log(a)? //=>12
console.log(window.a)? //=>12
var a = 12,b = 13;//這樣寫B(tài)是帶VAR的
var a = b = 12;? //這樣寫B(tài)是不帶VAR的
面試題? -- 帶VAR和不帶VAR的
console.log(a,b)? // undefined? undefined
var a = 12,
b = 12;
function fn(){
????console.log(a,b)? //undefined,12
????/*
? ? ? ?* 私有作用域中daiVAR和不帶VAR也有區(qū)別
? ? ? ?* 私有作用域下帶VAR的是私有變量,帶VAR的私有作用域變量提升階段憎夷,都聲明為私有變量莽鸿,和外界沒有關(guān)系
? ? ? ?* 不帶VAR的不是私有變量,會向它的上級作用域查找拾给,看是否為上級變量祥得,不是,繼續(xù)向上查找蒋得,一直找到window為止(我們把這種查找機制叫做:“作用域鏈”)级及,也就是我們在私有作用域中操作的這個非私有變量,是一直操作別人的额衙。
? ? ? ? */
? ? ? ?var a = b =13; //(b不是私有變量的? ?/* var a = 13;b = 13; */
????????console.log(a,b)? //13,13
}
fn();
console.log(a,b)? ? // 12,13
面試題 -- 在私有作用域中 b = 13饮焦,輸出
function fn(){
????/*
????* 變量提升
????*/
????console.log(b) //: b is not defined
????b = 13;
????console.log('b' in window);? //=>true 在作用域鏈中查找的過程中,如果找到window也沒有這個變量窍侧,相當(dāng)于給window設(shè)置了一個屬性B
????console.log(b); // =》 13
}
fn();
console.log(b);? // =>13