DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> JavaScript基礎知識 >> 一道面試題讓你與JS更近一步
一道面試題讓你與JS更近一步
編輯:JavaScript基礎知識     

這是一道面試題, 請先思考,在看講解 :)

var param = 1;

function main()
{    
    console.log(param);
    var param = 2;
    console.log(this.param);
    this.param = 3;
}

//下面兩條語句分別會在控制台打印什麼?
main();
var m = new main();

 

講解如下:

1. main() , 打印的結果為: undefined1

 

a. >  來看第一個打印的值為什麼是 undefined。 在js中,方法和變量的聲明都是會提前的。也就是說不管你在何處聲明的方法或者變量,在js解析時,都會將其提前,具體看代碼

demo(); //此處能正常彈出 similar

function demo()
{
    alert("similar");
}

按照js的語句執行順序,應該是從上自下依次執行的。 也就是說會先執行demo(), 然而這個時候demo()還沒有聲明,並不存在,應該報錯才對,為什麼還能正常彈出similar呢?這就前面說的方法聲明在js解析時會提前。所以上面的代碼,經過解析之後,就相當於

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作用域鏈及變量查找, 之後我會寫一篇於此相關的講解文章】

 

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(), 打印的結果為: undefinedundefined

 

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();

說到底這裡還是一個關於 js 中 this 的理解的問題,掌握了this , 此問題就很好理解了。現在都知道各中緣由了,是不是有種豁然開朗的感覺,哈哈...

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved