1、JS中的內存空間分為兩種:棧內存、堆內存
棧內存:提供JS代碼執行的環境;存儲基本數據類型的值; ->全局作用域或者私有的作用域其實都是棧內存
堆內存:存儲引用數據類型的值(對象是把屬性名和屬性值存儲進去,函數是把函數體中的代碼當做字符串存儲進去)
2、當浏覽器加載我們HTML頁面的時候,首先會提供一個供JS代碼執行的環境->全局作用域(global->window)
3、在JS代碼執行之前,浏覽器還需要自己做一些事情:把所有帶var/function關鍵字的進行提前的聲明或者定義 ->"預解釋"(變量提聲)
聲明(declare) -> 告訴浏覽器我有這樣一個東西啦,例如 var num1; function fn;
定義(defined) -> 給我們聲明的變量或者函數賦值,例如 num1=12; fn=function(){}
[重要]變量只聲明沒有定義,默認的值是undefined(未定義)
4、var和function在預解釋階段處理是不一樣的
var -> 在預解釋的時候只是提前的聲明了這個變量,只有當代碼執行的時候才會完成賦值操作
function -> 在預解釋的時候會提前的把聲明加定義都完成了(在代碼執行的時候遇到定義的代碼直接的跳過)
[重要]剛開始只對window下的進行預解釋,fn函數中目前存儲的都是字符串,所以var total沒啥實際的意義,所以不進行預解釋 -> "預解釋是發生在當前作用域下的"
console.log(obj);//->undefined var obj = {name: "張珊珊", age: 10}; function fn(num1, num2) {//代碼執行到這一行的時候直接的跳過,因為在預解釋的時候我們已經完成了聲明加定義 var total = num1 + num2; console.log(total); } var num1 = 12; fn(num1, 100);//執行fn,把全局變量num1的值賦值給形參num1,把100賦值給形參num2
5、在全局作用域下聲明的變量是全局變量
在私有作用域中聲明的變量是私有變量;函數的形參也是私有的變量;
如何分辨函數中出現的變量是私有的還是全局的?
首先看是否為形參,然後看是否在私有作用域中聲明過(有沒有var過),兩者有其一就是私有的變量,那麼在當前函數中不管什麼位置出現都是私有的,和全局的沒有半毛錢的關系;如果兩者都沒有,說明不是私有的,則往其上一級作用域進行查找...
6、函數執行的時候會形成一個新的私有的作用域(棧內存),供函數體中的代碼執行;
1)給形參賦值
2)私有作用域下的預解釋
3)私有作用域下的代碼執行
形成的新的私有的作用域還保護了裡面的私有變量不受外界的影響,我們把函數的這種保護機制->"閉包
區別:帶var的可以在代碼執行前進行聲明,而不帶var的不能提前的聲明
1、不管條件是否成立都要進行預解釋
window預解釋:var a; -> window.a; if (!("a" in window)) {//"a" in window -> true var a = "我們"; } console.log(a);//->undefined
2、預解釋只發生在"="的左邊,只把左邊的進行預解釋,右邊的是值是不進行預解釋的
匿名函數之函數表達式:把函數定義的部分當做值賦值給一個變量或者元素的事件
預解釋的時候:var fn; ->fn的默認值是undefined
fn();//->undefined() Uncaught TypeError: fn is not a function JS中只有函數可以執行 && JS上面的代碼如果報錯了,在不進行任何的特殊處理情況下我們下面的代碼都不在執行了 var fn = function () { console.log("ok"); }; fn(); 預解釋的時候:fn=xxxfff000 fn();//->"ok" function fn() { console.log("ok"); } fn();//->"ok"
3、函數體中return下面的代碼都不在執行了,但是下面的代碼需要參加預解釋;而return後面的東西是需要處理的,但是由於它是當做一個值返回的,所以不進行預解釋;
var total = 300; function fn() { console.log(total); return function sum() {};//return是把函數中的值返回到函數的外面,這裡是把function對應的內存地址返回的到函數的外面,例如:return xxxfff111;函數體中return下面的代碼都不在執行了 var total = 10; } fn();
4、匿名函數的function在全局作用域下是不進行預解釋的
匿名函數之自執行函數:定義和執行一起完成了
(function(num){})(100);
5、在預解釋的時候,如果遇到名字重復了,只聲明一次,不重復的聲明,但是賦值還是要重復的進行的
在JS中變量的名字和函數的名字如果一樣是算作重復的
預解釋:
var fn; 聲明 fn = xxxfff000; [聲明]不要了+定義 fn = xxxfff111; [聲明]不要了+定義 ->fn=xxxfff111 var fn = 12;//window.fn=12 function fn() {//window.fn=function(){} } function fn() { }
以上就是小編為大家帶來的關於JS 預解釋的相關理解全部內容了,希望大家多多支持~