console.log(num);//報錯,num is not defined,此錯誤在執行時出現,而非預解析時出現如何聲明?(1)聲明變量var num;注意:① 重復聲明無效② 如果變量賦值,沒有使用 var,那么會稱為全局變量(注意:嚴格模式中報錯)"use strict"; //嚴格模式③ 連續聲明多個變量時一定要注意符號var num1, num2, num3, num4;//不要少了符號var num1 = 1,num1 = 1,num1 = 1,num1 = 1;(2)函數聲明function 函數名() { // 函數聲明}同時需要注意:函數聲明必須獨立于語句,成為一個單獨的代碼結構,只允許出現在全局范圍內和函數中的全局范圍內if(1){ function f() { //不是聲明 }}function foo(){ function f() { //在函數內聲明 }}3. 什么是記錄聲明
(1)代碼片段1foo();function foo() { console.log('ok');}代碼在執行之前會先預解析,檢查到有函數聲明,因此在執行代碼之前,js 引擎就知道有函數 foo 了,因此在執行代碼時調用 foo 就不會報錯。(2)代碼片段2foo();//foo is not defined+function foo() { console.log('ok');}函數不是一個獨立的存在,是一個和 + 連接的表達式,因此在預解析的時候沒有檢查到聲明,因此瀏覽器不會記錄函數,在第一次調用的時候就會出現錯誤。(3)代碼片段3foo();//foo is not a functionvar foo = function () { console.log('ok');};在代碼執行之前,預解析檢查到有 foo 聲明(變量),因此記錄變量 foo在代碼執行的第一句調用函數(此時還未賦值),報錯,foo不是一個函數(4)在預解析的時候,記錄聲明由兩部分構成① 如果是變量聲明,那么就記錄下變量名,并且將其值確定為 undefined② 如果是函數聲明,要記錄函數名和函數體首先在內存記錄下有一個名字,和變量名的聲明此時的規則是一樣的;緊接著記錄下函數體,將函數名和函數體聯系在一起練習:console.log(a);//打印函數體a();//'a'var a = 10;a();//報錯,a is not functionfunction a(){ console.log('a');}a();//報錯,a is not functionconsole.log(a);//10代碼分析:① 預解析,檢查到有聲明,變量與函數首先預解析到有變量a存在,因此記錄下a這個名字,和其值undefined;接著預解析到有函數a聲明,記錄下函數名a,但是發現已經記錄了一個a,因此該操作無效,將函數體與a這個名字相關聯,解析完畢。② 開始逐步執行代碼賦值語句,執行給a重新賦值為10,將存儲的關聯函數覆蓋;執行console.log打印,打印出a的值,由于a中存儲的是數字10,因此打印10③ 分析完代碼后,將上述代碼轉換成下列形式(注意:不是所有代碼都可以這樣轉換)
新聞熱點
疑難解答