摘要:預解釋基礎知識先介紹的基本數據類型基本數據類型值操作有引用數據類型引用地址執行環境當瀏覽器加載頁面的時候,首先會提供一個供全局代碼執行的環境全局作用域如下代碼是在中好好學習天天向上把整個函數定義的部分函數本身在控制臺輸出
預解釋 1. JS基礎知識 1.1 先介紹js的基本數據類型
基本數據類型 --- 值操作
有number、string、boolean、null、undefined
引用數據類型 ---- 引用地址
object、array、Date
1.2 執行環境當瀏覽器加載HTML頁面的時候,首先會提供一個供全局JS代碼執行的環境 --- 全局作用域(global/window)
如下代碼是在script中
var num = 12; var obj = { name:"houdashuaige", age:18 }; function fn() { console.log("好好學習 天天向上"); } console.log(fn) //把整個函數定義的部分(函數本身)在控制臺輸出 console.log(fn()) //輸出當前函數的執行返回結果 fn()//return 后面是啥 返回啥 如果沒有return 返回undefined
示意圖如下
如果執行obj.age = 20; 首先通過地址xxxfff000 找到對應的空間 然后把空間中age屬性對應的屬性值修改為20; 其中fn存儲的是一個地址 代表的時當前函數的整體2. 預解釋 2.1 預解釋的基本概念
在當前的作用域中,JS代碼執行之前,瀏覽器首先會默認地把所有帶var、function的進行提前的聲明或者定義2.1.1 理解聲明(declare)和定義(defined)
var num = 12; 聲明: var num; //告訴瀏覽器在全局作用域中有一個num的變量 定義: num = 12(發生在代碼執行過程中 不在預解釋中); //給變量進行賦值 function fn() { console.log("this is a test"); } 函數預解釋 fn = xxxfff000; 聲明: fn //告訴瀏覽器在全局作用域中有一個fn的函數 定義: fn = xxxfff000; //給fn賦值 指向函數的地址
注釋: 所以對于帶var 和 function關鍵字的在預解釋的時候操作還是不一樣的
**var: 對于帶var的變量 預解釋只會聲明 不會進行定義** **function: 在預解釋的時候聲明+定義 一起完成了**
附代碼
//函數只有在執行的時候才會對函數內部的代碼進行預解釋 console.log(num);// undefined 提前聲明 但未定義 默認undefined var num = 12; console.log(num);// 12 var obj = { name: "hou", age: 7 }; fn(100,200);//代碼可以在這執行 因為預解釋的時候 聲明+名義就已經完成了 function fn(num1,num2) { var total = num1 + num2; console.log(total); }
附示意圖
2.1.2 函數預解釋(代碼內部)function fn(num1,num2) { var total = num1 + num2; console.log(total); }
附示意圖
2.1.3 JS中內存的分類(預解釋發生在棧內存)//棧內存:用來提供一個供JS代碼執行的環境 --->作用域(全局作用域/私有作用域) //堆內存:用來存儲引用數據類型的值 --->對象存儲的時屬性名和屬性值 //函數存儲的是代碼字符串2.1.4 如何區分私有變量和全局變量(主要用來分析函數預解釋)
注釋: 下述都是為了更好地理解"函數預解釋",請耐心閱讀
"全局作用域"下聲明(預解釋的時候)的變量是全局變量
在"私有作用域"中聲明的變量和"函數的形參"都是私有的變量
在私有作用域中,我們代碼執行的時候遇到了一個變量,首先我們要確認它是否是私有的變量,
如果是私有的變量,那么和外面的變量沒有任何的關系,如果不是私有的,則往當前作用域的
上級作用域查找,如果上級作用域沒有則繼續查找,一直找到window為止 --->("作用域鏈")
當函數執行的時候(直接目的:讓函數體中的代碼執行),首先會形成一個新的私有作用域,然后按照如下步驟執行:
a:如果有形參,先給形參賦值
b:進行私有作用域中的預解釋
c:私有作用域中的代碼從上到下執行
函數形成一個新的私有作用域保護了里面的私有變量不受外界的影響(外面修改不了私有的,私有的也修改不了外面的)形成了"閉包" --->(保護機制)
2.1.5 全局作用域中,帶var和不帶var的區別區別1: 帶var的可以進行預解釋,所以在賦值的前面執行不會報錯,不帶var的是不能進行預解釋的,在前面執行會報錯
代碼如下
console.log(num);--->undefined var num = 12; console.log(num2); --->直接報錯 因為num2沒有預解釋 num2=13;
區別2: 看下述代碼
var num = 12; console.log(num);//12 num2 = 12; console.log(num2) //12 --->相當于window.num2 //關系:num2 = 12 --->相當于給window增加了一個叫num2的屬性名,屬性值是12 //var num =12 --->相當于給全局作用域增加了一個全局變量num,但是不僅如此, //它也相當于給window增加了一個屬性名num,屬性值是12
函數內部不帶var的代碼如下
var total = 0; function fn() { console.log(total) // 0 total = 100;//相當于修改了全局變量total } fn(); console.log(total)//--->100 //注釋:私有作用域中出現的一個變量不是私有的,則往上級作用域查找,上級沒有則繼續向上查找,一直找到window //如果window下沒有 分兩種情況: //1、如果是獲取值:console.log(total) -->直接報錯 //2、如果是設置值:total = 100;--->相當于給window加了total屬性 //3、JS中如果在不進行任何特殊處理的情況下,上邊的代碼報錯,下邊的代碼都不執行了2.1.6 預解釋是一種毫無節操的機制
預解釋的時候不管你的條件是否成立,都要把帶var的進行提前聲明
具體代碼如下
if(!("num" in window)) { //===>if(false) var num = 12; } console.log(num);//--->實際輸出undefined //分析:不管if的條件是否成立 都會把帶var的進行預解釋 (var num = 12) //所以"num" in window 是true !("num" in window) --->false //if條件是false var num = 12 不會執行 所以 console.log(num) 是undefined
匿名函數之函數表達式
把函數定義的部分當作一個值賦給我們的變量/或者賦給元素的某一個事件
fn();//====>fn 是undefined 相當于 undefined() 報錯 uncaught TypeError: fn is not a function //window下的預解釋 var fn; 預解釋的時候只會預解釋 "="(等號)左邊的 //右邊的是值 不參與預解釋 var fn = function() { console.log("ok"); }
自執行函數
定義和執行一起完成的
//自執行函數定義的那個function在全局作用域下不進行預解釋,當代碼執行到這個位置的時候,定義和執行一起完成了 //自執行函數的5種形式 (function(num){})(100);//常用形式 ~function(){}(100); +function(){}(100); -function(){}(100); !function(){}(100)
函數內部return相關
function fn() { console.log(num);//--->undefined return function() {}; var num = 100; } fn(); //函數體種return 下面的代碼雖然不再執行了,但是需要進行預解釋 //return 后邊跟著的是我們的返回值,所以不進行預解釋
預解釋經典習題解析
//注釋:在預解釋的時候,如果名字已經聲明過了,不需要重新聲明,但是需要重新定義(賦值) //JS比較懶,聲明過一次,便不再聲明,但是可以重新定義 //在JS中,如果變量的名字和函數的名字重復了,也算沖突 fn(); function fn() {console.log(1)}; fn(); var fn = 10; fn(); function fn() {console.log(2)}; fn(); //輸出結果是2 、2 、 報錯:fn is not a function 后邊代碼不執行
附解釋圖
(自己畫預解釋圖 學習 分析會更快 更有效)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/100249.html
摘要:預編譯發生在函數執行前也就是說函數執行時,預編譯已經結束。五總結理解預編譯需要明白變量函數聲明和變量賦值。預編譯階段,只進行變量函數聲明,不會進行變量的初始化即變量賦值,所有變量的值都是變量賦值是在解釋執行階段才進行的。 一、JS的概念 JavaScript ( JS ) 是一種具有函數優先的輕量級解釋型或即時編譯型的編程語言。 二、JS語言特點 2.1 單線程 (1)JavaScri...
摘要:進階第一章作用域深入和面向對象預解釋全局作用域當瀏覽器加載頁面的時候,提供了一個全局代碼執行的環境預解釋變量提升在當前的作用域中,代碼執行之前,瀏覽器首先會默認的吧所有帶有和的進行提前聲明或定義理解聲明和定義聲明告訴瀏覽器在全局作用域中有 JS進階 第一章作用域深入和面向對象 預解釋 1、全局作用域:當瀏覽器加載HTML頁面的時候,提供了一個全局js代碼執行的環境 2、預解釋(變量提升...
摘要:一概念是一個單線程解釋型的編程語言。預編譯大致可分為步創建對象找形參和變量聲明,將形參和變量名作為屬性名,值為將實參值和形參統一在函數體里面找函數聲明,值賦予函數體。 一、JavaScript概念 JavaScript ( JS ) 是一個單線程、解釋型的編程語言。 二、JavaScript語言特點 2.1 單線程 JavaScript語言的一大特點就是單線程,也就是說,同一個時間只能...
摘要:大家都知道是解釋型語言,既然是解釋型語言,就是編譯一行,執行一行,那又何來預編譯一說呢腳本執行引擎都做了什么呢今天我們就來看看吧。全局域就是一切聲明的全局變量,全是的屬性等同于函數預編譯發生在函數執行前一刻。 大家都知道JavaScript是解釋型語言,既然是解釋型語言,就是編譯一行,執行一行,那又何來預編譯一說呢?腳本執行js引擎都做了什么呢?今天我們就來看看吧。 1-JavaScr...
閱讀 1106·2021-10-14 09:43
閱讀 1151·2021-10-11 11:07
閱讀 3114·2021-08-18 10:23
閱讀 1490·2019-08-29 16:18
閱讀 1003·2019-08-28 18:21
閱讀 1478·2019-08-26 12:12
閱讀 3761·2019-08-26 10:11
閱讀 2505·2019-08-23 18:04