要寫出嚴謹的代碼或者是優化性能就必須作到‘知己知彼’,爲此把握事物規律方能有備無患,穩步前進,故對此有所探知。函數
var a = 5; function f(n){ alert(a); } f();
上面代碼的全局處理過程:性能
一、預處理階段優化
a、讀取分析整個源代碼 b、先掃描函數聲明,以後掃描變量(var聲明) b_a、處理**函數聲明**時有衝突,會覆蓋 b_b、處理變量聲明時有衝突,會忽略(相對函數聲明) c、將掃描到的函數和變量保存到一個對象中(全局的保存到window對象中) d、變量的值是undefined,函數的值則指向該函數(是一個函數字符串) 形式以下:{a : undefined, f : 'function(){alert(a);}'}
二、運行階段code
在咱們剛剛的案例中 a、將變量a的值從undefined改成5 b、調用f(),一遍函數獲得執行
上面函數代碼的處理過程:對象
**一、預處理階段** a、將函數的參數添加到一個對象(**詞法對象**) b、掃描**函數聲明**,以後掃描變量(var聲明) d、將掃描到的函數和方法添加到詞法對象裏面 c、變量的值是undefined,函數的值則指向該函數(與全局的同樣) 二、運行階段 與全局的的運行原理同樣
var b = 1; function ff(){ alert(b); var b = 5; alert(b); } ff(); //結果彈出爲:undefined
緣由:ci
js在預處理階段時,將函數ff()和變量b保存到window對象中,字符串
此時b = undefined,到了運行階段,b = 1,這時調用函數ff(),it
js會先把函數內的變量添加到詞法對象中,此時b = undefined,io
再以後alert(b),由於是在方法內部,因此alert(b)會調用詞法console
對象中的b。然而這時詞法對象中的b = undefined,因此執行結
果彈出的是undefined,當alert執行完以後b = 5;
alert(a); function a() { console.log("xx"); } var a = 5; function a() { console.log("yy"); } //運行結果:'function a() { console.log("yy"); }'
緣由:
咱們發現變量a和兩個方法a()同名了,這時,js在預處理的時候
會優先將函數保存到window對象中,而後若是發現同名的是
變量,這時它會忽略這個變量;若是發現同名的是函數,那
麼後面的會將前面的覆蓋。因此執行alert彈出的會是函數
alert(b); var b = 5; var b = function () { console.log("xx"); } //運行結果:undefined
緣由:
咱們知道,定義一個方法有多種形式。像上面這個案例中,
咱們的函數是匿名的,而後賦值給了一個變量。但變量終究
是變量,js不會由於它的值比較特別就特殊對待,因此,在
js在預處理的時候,先將第一個變量b保存到window中,此時
變量b=undefined,而後第二個變量b覆蓋了第一個變量,此時
的變量b依然仍是等於undefined,因此在程序運行的時候彈出
值會等於undefined。
function c(num1){ alert(num1); } c(2); //運行結果:2 function d(num2){ alert(num2); var num2 = 5; } d(2); //運行結果:2
緣由:
在運行前,我就猜測彈出的這個應該是一個undefined的
可沒想到倒是2,這使我百思不得其解。
在js預處理的時候讀取到了這個函數有一個參數,因而就
直接將這個參數放到了詞法對象中,這時個參數的值是
undefined,以後它繼續向下掃描,發現有一個變量定義,
但咱們卻發現這變量與參數同名,這個時候js會怎麼作?
這時按照以前所學的,這個變量會被加到詞法對象中,而
事實上也的確是加了,不過卻給它打上了一個標籤,用來
標識這個變量是一個參數,這時這個變量的值也是undefined。
當程序真正運行的時候,咱們把參數傳過去,這個參數就會賦值的到這個參數中,
而後彈出結果,而後再賦值爲5。
接下來還有幾個問題
1.看下面代碼
funciton f(num){ alert(num); funciton num(){ } } f(6);
返回結果爲:'funciton num(){}'
像出現上面這個狀況的時候,js也仍是同樣在預處理的時
候,將參數放到詞法對象中,而後發現裏面有一個同名的
函數,這時js就會把這個函數放到詞法對象中,並覆蓋之
前的參數,而它的值指向的就是這個函數。當咱們程序真
正運行時,咱們把參數傳過去,js在這裏並不會把6這個參
數值賦值給這個形參。