<script type="text/javascript"> alert(i);//Uncaught ReferenceError: i is not defined i=11; </script>
<script type="text/javascript"> alert(i);//undefined var i=11; alert(i);//11 </script>
代碼1:javascript
var name="hello" function f1(){ console.info(name); var name="world"; console.info(name); } f1();
輸出結果:java
undefined;
world;
代碼2:編程
var name="hello" function f1(){ console.info(name); } f1();
輸出結果:函數
hello
var param = 1; function main() { console.log(param); var param = 2; console.log(this.param); this.param = 3; } //下面兩條語句分別會在控制檯打印什麼? main(); var m = new main();
講解以下:this
1. main() , 打印的結果爲: undefined , 1spa
a. > 來看第一個打印的值爲何是 undefined。 在js中,方法和變量的聲明都是會提早的。也就是說無論你在何處聲明的方法或者變量,在js解析時,都會將其提早,具體看代碼prototype
demo(); //此處能正常彈出 similar function demo() { alert("similar"); }
按照js的語句執行順序,應該是從上自下依次執行的。 也就是說會先執行demo(), 然而這個時候demo()尚未聲明,並不存在,應該報錯纔對,爲何還能正常彈出similar呢?這就前面說的方法聲明在js解析時會提早。因此上面 的代碼,通過解析以後,就至關於code
function demo() { alert("similar"); } demo(); //此處能正常彈出 similar
因此纔會正常彈出 similar。 那麼對於變量的聲明也是同樣的,會提早。 咱們上面的代碼,通過解析以後實際上等同於下面的代碼對象
var param; //聲明提早 param = 1; function main() { var param; //聲明提早 console.log(param); //由於此時 param 只是進行了聲明,並未賦值,因此 打印的是 undefined param = 2; console.log(this.param); this.param = 3; }
這裏你或許會感到疑惑。咱們在main()方法外面不是已經賦值爲1了嗎? 這是由於,咱們在main()方法裏面也定義了一個同名的 param。 就近原則,js會先查找本身有沒有這個變量,若是有,就用本身的,若是沒有就向上級查找,上級仍是沒有就到上上級去查找,如此循環,在哪找到,就在哪停 止。若是全都沒有,就返回undefined。 【這裏涉及到一個知識點: js做用域鏈及變量查找, 以後我會寫一篇於此相關的講解文章】blog
b. > 如今咱們再來看看第二打印的值爲何是1。 我將代碼再作一次等價轉換,這樣或許你們就更容易明白原因了,轉換後代碼以下
window.param = 1; //全局變量 param // 全局方法 main() window.main = function () { console.log(param); var param = 2; console.log(this.param); //此時的this指代的就是 window, 所以 this.param = window.param = 1 this.param = 3; }
//調用全局方法main() window.main();
看到這裏,你們是否有些明白了呢?由於 main() 方法和 main() 方法外面的 param 都是定義在最外層的(沒有包裹在其餘對象裏面),所以他們都是全局對象window下的成員。 當咱們調用 main() 方法時, 實際上就是調用的 window.main(); 而經過這樣的方式調用時, this 指代的就是全局對象 window。 因此第二個打印的值爲 1。【這裏涉及到一個知識點: js中讓人迷糊的this,以後我會寫一篇於此相關的講解文章】
2. var m = new main(), 打印的結果爲: undefined, undefined
a. > 第一個打印的值爲 undefined 的緣由和上面的緣由是同樣的,都是由於變量聲明提早致使的。
b. > 那麼第二個打印的值也爲 undefined 的緣由是什麼呢? Js也是支持面向對象式編程的語言,然而js中卻沒有類的概念,而是使用基於原型(prototype)的繼承。 所以呢,js中的構造函數也很特別,通常狀況下它和普通方法沒什麼區別,只有經過 new 關鍵字來調用的時候才能體現出其做爲構造函數的功能。 而此處正是把 main() 和 new 關鍵字一塊兒使用,說明此時的main()是一個構造函數。而構造函數中的 this 指代的就是新建立的對象,那麼也就是 m 。
var param = 1; function main() { var param; //聲明提早 console.log(param); //由於此時 param 只是進行了聲明,並未賦值,因此 打印的是 undefined param = 2; console.log(this.param); //構造函數中的this指代的是新建立的對象,咱們這裏新建立的對象是 m , 因此 this.param = m.param , 而此時 this.param 還沒有賦值,因此打印的是 undefined (此處我本身也有一個疑問: 構造函數中的屬性的聲明會提早嗎?也就是 this.param 的聲明會提早嗎? 求解) this.param = 3; } var m = new main();