1. 程式人生 > >JavaScript預解析:同名變數和函式、同名函式表示式和同名函式宣告,執行哪個和變數提升的坑

JavaScript預解析:同名變數和函式、同名函式表示式和同名函式宣告,執行哪個和變數提升的坑

先說下預解析的含義,在寫js程式碼呼叫函式的時候,無論你是在呼叫位置的前面或者後面宣告函式,都可以正常呼叫,原因是,JavaScript碰到script標籤,會將var變數(注意是var)宣告和函式宣告(注意是宣告)提升到當前作用域最前面。

要想搞懂預解析,先記住結論:

變數的提升,指的是宣告的提升,賦值(初始化)並不會提升

接下來 就對著這個結論看一些例子:

例1:

console.log(num); //undefined
    var num = 2;

變數宣告提升,賦值不提升,所以上述程式碼相當於:

var num;
console.log(num);
num = 2;

例2:

var num = 2;
var num;
console.log(num); //2

是不是以為是undefined呢?千萬別忘了變數是會提升的,看下面程式碼就明白為什麼是2了:

var num;
var num;
num = 2;
console.log(num);

這裡有個問題,看下面程式碼:

function f() {}
var f
console.log(f); //function f() {}

 按理說,這裡應該是undefined,結果明顯不是,這裡個人以為可以理解成,變數的宣告提升後會在函式前面

再將程式碼作如下修改:

function f() {
console.log(num); // undefined
}
var num

這裡函式裡面能訪問到num,證明變數的宣告會在函式宣告之前

這個問題是個人的理解,有疑問的讀者也可以去查些資料。 

例3:

var f = function() {
   console.log(1)
}
function f() {
  console.log(2)
}
f(); // 1

這個例子結果是1的原因,可以看下面的程式碼:

var f;
function f() {
   console.log(2)
}
f = function() {
  console.log(1)
}
f();

例4:

f(); // 2
var f = function() {
  console.log(1)
}
function f() {
  console.log(2)
}

這個例子和前一個只是函式呼叫位置發生了改變,結果也變了,可以嘗試自己按照步驟一步步重新寫在紙上,結果如下:

var f;
function f() {
  console.log(2)
}
f();
f = function() {
  console.log(1)
}

例5:

f(); //報錯
var f = function(){
   console.log('k')
}

這個例子應該很簡單,只是將例1中的變數換成了函式:

var f;
f();
f = function(){
  console.log('k')
}

呼叫一個未賦值的函式,當然會報錯,注意一下,這個例子,將函式表示式換成函式宣告就不會報錯了,因為函式宣告會提升,這也是我們常用函式宣告的一個原因,可以在任何位置呼叫。

例6:

var num = 2;
function f() {
  num = 1;
  console.log(num); //1
  return
  var num = 3;
}
f();
console.log(num) //2

return後面的語句雖然不會執行,但是變數還是會提升:

var num = 2;
function f() {
   var num
   num = 1;
   console.log(num); //1
   return
   num = 3;
}
f();
console.log(num) //2

例7:

console.log(num);// 報錯
num = 2;

我們開篇就說過,只有var會提升,隱式全域性變數並不會提升,所以結果和例1不同,並不是undefined

相關推薦

JavaScript解析同名變數函式同名函式表示式同名函式宣告執行哪個變數提升

先說下預解析的含義,在寫js程式碼呼叫函式的時候,無論你是在呼叫位置的前面或者後面宣告函式,都可以正常呼叫,原因是,JavaScript碰到script標籤,會將var變數(注意是var)宣告和函式宣告(注意是宣告)提升到當前作用域最前面。 要想搞懂預解析,先記住結論:

javascript解析函式做引數

1. 預解析:提前解析程式碼 console.log("num");// 輸出-undefined var num=10; 預解析是: var num; console.log("num");// 輸出-undefined num=10; 2. arguments 物件 可將獲取的多個值

javascript解析詳解

ole 標簽 scrip defined cti con body his 字符串 1、定義 預解析:在當前作用域下,js運行之前,會把帶有var和function關鍵字聲明的變量先聲明,並在內存中安排好。然後從上至下解析js語句。而且function的聲明優先於var聲明

前端(十三)—— JavaScript高級回調函數閉包循環綁定面向對象定時器

set 執行 使用 一次 name屬性 解決案例 就會 請求 事件 回調函數、閉包、循環綁定、面向對象、定時器 一、函數高級 1、函數回調 // 回調函數 function callback(data) {} // 邏輯函數 function func(callback)

Tomcat原始碼解析Jsp檔案的編譯實現

1.Jsp簡介     jsp(java server page),其根本是一個簡化的Servlet技術,是一種動態網頁技術標準。     它是在傳統的網頁HTML頁面中插入java程式碼段,從而形成jsp檔案,字尾為.jsp。  

Redis原始碼解析25叢集(一)握手心跳訊息以及下線檢測

         Redis叢集是Redis提供的分散式資料庫方案,通過分片來進行資料共享,並提供複製和故障轉移功能。 一:初始化 1:資料結構 在原始碼中,通過server.cluster記錄整個叢集當前的狀態,比如叢集中的所有節點;叢集目前的狀態,比如是上線還是下線;

編寫一個可變引數的C函式——標頭檔案stdarg.h中巨集va_start va_argva_end的應用

我們在C語言程式設計中會遇到一些引數個數可變的函式,例如printf()這個函式,它的定義是這樣的:int printf( const char* format, ...);它除了有一個引數format固定以外,後面跟的引數的個數和型別是可變的,例如我們可以有以下不同的呼叫方

JavaScript事件代理尋找target目標元素求結點深度

基礎知識儲備 本文的出彩之處在最後兩部分,前面只是基礎介紹。 JS中的事件代理,網上有很多大神已經介紹的非常完美了,這裡無需我的贅述。在學習事件代理之前,最好把事件模型學習了,就是捕獲階段、目標階段、冒泡階段 那些事情。這裡,我推薦兩篇別人的文章:

利用sortuniq求兩個文件的並集交集差集

sort uniq  利用sort和uniq求兩個文件的並集,交集和差集  並集:cat file1.txt file2.txt | sort | uniq > file.txt  交集:cat file1.txt file2.txt | sort | uniq -d >file.txt 

es6 陣列例項的 entries() keys() values() ES6 提供三個新的方法 —— entries()keys()values() —— 用於遍歷陣列。它們都返回一個遍歷器物件可以用for...of迴圈進行遍歷唯一的區別是keys()是對鍵名的遍歷values(

ES6 提供三個新的方法 —— entries(),keys()和values() —— 用於遍歷陣列。它們都返回一個遍歷器物件,可以用for...of迴圈進行遍歷,唯一的區別是keys()是對鍵名的遍歷、values()是對鍵值的遍歷,entries()是對鍵值對的遍歷

第6章建立函式-----------(在.bashrc檔案中定義函式在命令列建立函式在命令列中使用函式)

6.6在命令列中使用函式          指令碼函式可以用於建立比較複雜的操作。指令碼函式不僅可以用作shell指令碼命令,也可以用作命令列介面的命令。一旦在shell中定義了函式,可以從系統的任意目錄使用這個函式。不必擔心PATH環境變數是否包含函式檔案所在目錄。關鍵是

Numpy中reshape函式reshape(1,-1)的含義(淺顯易懂原始碼例項)

本文詳細介紹numpy中reshape函式的三種常見相關用法。 一般用法:numpy.arange(n).reshape(a, b); 依次生成n個自然數,並且以a行b列的陣列形式顯示: In [1]: np.arange(16).reshape(2,8) #生成16個

第112天javascript中函數解析執行階段

col 對象 全部 內存空間 div 實現 undefined 私有 分解 關於javascript中的函數:   1、預解析:把所有的函數定義提前,所有的變量聲明提前,變量的賦值不提前   2、執行 :從上到下執行,但有例外(setTimeout,setInterval,

進擊JavaScript核心 --- (2)函式解析機制

一、函式 每個函式都是 Function型別的例項,也具有屬性和方法。由於函式也是一個物件,因此函式名實際上也是一個指向函式物件的指標,不會與某個函式繫結 1、函式的定義方式 (1)、函式宣告 function add(a, b) { return a + b; }

解析用 CSS3 JavaScript 制作徑向動畫菜單

select webkit on() making 它的 text tran 表示 har 原作者的解析(英文):http://creative-punch.net/2014/02/making-animated-radial-menu-css3-javascript

JavaScript函式(定義與解析匿名函式函式傳參return關鍵字)陣列(操作資料的方法多維陣列陣列去重)

函式 函式就是重複執行的程式碼片。 1、函式定義與執行 <script type="text/javascript"> // 函式定義 function aa(){ alert('hello!'); } // 函式執行

jQuery原始碼解析變數函式

 //原始碼剖析都基於jQuery-2.0.3版本,主要考慮到相容IE 2行:jQuery javaScript Library v2.0.3——jQuery版本 3行:http://jQuery.com——官網 5~6行:Includes Sizzle.js;http://sizzlejs.

JavaScript變數作用域函式作用域宣告提前

1.變數作用域 在函式體內,區域性變數的優先順序高於同名的全域性變數。如果在函式體內宣告的一個區域性變數或者函式引數中帶有的變數和全域性變數重名,那麼全域性變數就被區域性變數所遮蓋。 儘管在全域性作用域編寫程式碼可以不寫var語句,但宣告區域性變數時則必須使用v

一些概念結構名稱空間複製建構函式作用域連結性 自動變數堆疊

  1、類和結構       類描述看上去很像是包含成員函式以及public和private可見性標籤的結構宣告。實際上,C++對結構進行了擴充套件,使之具有與類相同的特性。他們之間唯一的區別是,結構的預設訪問型別是public,而類為pri

JS函式宣告解析的理解

JS函式宣告方法 今天看到了一個自己關注了的大神給我回了私信,覺得自己彷彿摸到了大神的褲腿,哈哈,而且人還特別好,居然會給小菜鳥回私信,特別開心呀,一個菜鳥的小激動,言歸正傳啦 1.最為常見的函式宣告的方式,function+函式名稱識別符號 func