一道面試題讓你與JS更近一步

来源:http://www.cnblogs.com/similar/archive/2016/03/18/5292926.html
-Advertisement-
Play Games

這是一道面試題, 請先思考,在看講解 :) 講解如下: 1. main() , 列印的結果為: undefined , 1 a. > 來看第一個列印的值為什麼是 undefined。 在js中,方法和變數的聲明都是會提前的。也就是說不管你在何處聲明的方法或者變數,在js解析時,都會將其提前,具體看代


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

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 , 此問題就很好理解了。現在都知道各中緣由了,是不是有種豁然開朗的感覺,哈哈...


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 先看效果: 方圖(w=h) 豎圖(h>w) 橫圖(w>h) 使用說明: // <![CDATA[ $(function(){ var zs=$(".zoom"); //添加放大鏡和影布 zs.append("<i class='magnifier'>"); zs.wrapInner("<sectio
  • 在 CSS 樣式定義中,以下哪種 RGB 顏色值是 Web 安全色? A]#111111B]#222222C]#333333D]#444444 答案:http://hovertree.com/tiku/bjaf/72jaf1n0.htm 解析:http://hovertree.com/h/bjaf/
  • [1]定義 [2]屬性 [3]失效 [4]應用
  • ExtJS為開發者在開發富客戶的B/S應用中提供豐富的UI組件,具有統一的主題,便於快速開發,提高效率。但顯然它並不適合互聯網站的開發。 一、主要目錄文件介紹 builds:壓縮後的ExtJS代碼,體積更小,更快; docs:開發文檔; examples:官方演示示例; locale:多國語言資源文...
  • html css
  • 自誕生之初截止目前(2016年初),React可以說是前端界最流行的話題,如果你還不知道React是何物,你就該需要充充電了。 d3是由紐約時報工程師開源的一個繪製基於svg的數據可視化工具,是近幾年最流行的visualization工具庫之一。d3提供豐富的svg繪製API、動畫甚至佈局等功能,目
  • 最近公司網站在谷歌,火狐上測試都沒有問題,但是在ietest,ie6上出現相容問題 ,由於ietest好幾次打開ie6都報錯(嘗試卸載重新安裝幾次無果),下載virtualbox安裝自帶ie6的xp系統,進行ie6測試,打開各大公司網站總是關閉,懷疑可能是xp的iso鏡像問題,於是又重新下載裝了第二
  • 斷斷續續的把慕課的JavaScript基礎和進階看完了,期間不怎麼應用有的都忘記了,接下來多開始寫些效果,進行實際應用。 製作一個表格,顯示班級的學生信息。 1. 滑鼠移到不同行上時背景色改為色值為 #f2f2f2,移開滑鼠時則恢復為原背景色 #fff 2. 點擊添加按鈕,能動態在最後添加一行 3.
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...