js 給一段代碼,給出運行後的最終結果的一些綜合狀況、

秋招快到了,咱們在準備筆試或者面試題的時候,常常會遇到一些題,給一段js代碼,回答運行後的結果是什麼,下面我來整理一下。java

一、做用域問題面試

(1)全局做用域閉包

值爲0函數

這個函數運行時,外面alert(x)拿到的是全局做用域中x的值,第一個聲明的var x=0;的值是全局做用域中的值,第二個在f函數中聲明的var x=2的值是局部做用域的值,由於用var從新聲明瞭一個變量,兩個指向的是不一樣的做用域,所以alert(x)返回的是0spa

(2)局部做用域3d

若是咱們把var x=2;中的var去掉,變成下面這樣子blog

值爲2作用域

出現這種狀況是由於,var x=0;聲明的是全局做用域的值,f()函數也是全局做用域,而後f函數中的值。x會覆蓋掉外部的值,所以就會致使獲得的值是2it

再來看一個例子io

這個值爲3,4,i is not defined

這個也是由於x,y有聲明而且在全局做用域中,這時就能獲得x,y的值,而i是在f函數中命名的,在外部的全局中就不能調用到。

若是將alert()語句放在f函數中,像下面這樣

值爲3,4,20

二、函數覆蓋問題

 值爲1,1

這裏f函數將x的值置爲1,而後雖然兩次調用f()函數,可是函數已經產生覆蓋,第一個函數覆蓋了第二個函數,所以兩次調用都是1

若是將上面的匿名函數f註釋掉,以下

值爲2,2

這時,已經不發生函數覆蓋,就一直是2,

若是將命名函數註釋掉

值爲1,1

像這樣,也不發生函數覆蓋,也是隻調用f函數、

要解決函數覆蓋的方法,就先寫命名函數,再寫匿名函數

值爲2,1

這樣的話,命名函數f()先調用,匿名函數f後調用

總結:之後寫函數時,儘可能寫成匿名函數形式,var f = function(){}

三、變量和函數提高問題

一、函數未定義

變量未定義,直接是undefined

二、函數已定義

這裏聲明瞭變量,js解釋器「前瞻性」查找全部變量定義,把它們「提高」到函數頂部,就出現undefined,第一個未定義就出現undefined,第二個定義了就出現1223

三、內部變量重複定義

這裏使用了閉包函數,第一個name變量提高,就會出現undefined,原本能夠訪問到全局做用域的name,可是內部已經從新聲明瞭,name變量提高,就會出現undefined。這裏典型的使用了函數聲明提早,函數體內的塊級做用域覆蓋住了外部name的全局做用域,而後因爲函數聲明提高,至關於在函數體內,先var name;而後console.log("Original name was"+name);而後name = "Underhill";console.log("New name is" + name);最後的值是同樣的。

所以,建議全部變量的定義,都放在頭部,並使用var a=XX,b=xxx這樣定義。

四、函數直接調用

這裏函數直接調用就沒什麼好說的

五、函數定義提高

函數定義提高僅僅做用域函數定義,而不做用於函數表達式

這裏函數definitionHoisted(),已經提高,而函數定義不做用於函數表達式,所以就拋出TypeError

六、命名函數表達式

在這裏,函數名字是funcName()是函數的一部分,不會獲得提高,而varName()也找不到這個方法

七、閉包函數與全局函數

var result = f1();就調用了f1()函數,這時result即爲f2,函數,result是全局變量

result()  調用完以後的值爲999,這時就是調用了f2函數,並將值輸出

nAdd(),調用完以後,這時nAdd()函數爲全局函數,也是閉包函數,值爲1000,

result(),這個調用f2函數,就輸出1000.

8.閉包中的命名提高。

 

這裏輸出的值是999,由於1000傳入進去,a的值被覆蓋了,a變量命名提高,輸出就是999;

 九、函數覆蓋問題

在js函數中,是沒有函數重載的,之前學java的時候,當函數名是相同的,主要傳遞的類型或者參數不一樣就會出現重載,兩個均可以用,可是在js中

主要出現兩個同名的函數,就會出現函數覆蓋,第二個add函數,覆蓋第一個add函數,而後,因爲函數聲明提早,就會直接將函數覆蓋。

 

那麼什麼是函數聲明提早呢?

函數聲明提早就是變量在變量聲明以前就是已經可用,通常用在函數體內,在一個函數體內是塊級做用域,通常函數,內部同名函數會覆蓋外部同名函數,而後又因爲函數聲明提早,就能夠有值。

That's all,Thank you!

相關文章
相關標籤/搜索