搜尋
首頁web前端js教程很多前端程式設計師經常忽略的一個JavaScript面試題的總結

很多前端程式設計師常忽略的一個JavaScript面試題的總結:

前言

年前剛剛離職了,分享下我曾經出過的一道面試題,此題是我出的一套前端面試題中的最後一題,用來考核面試者的JavaScript的綜合能力,很可惜到目前為止的將近兩年中,幾乎沒有人能夠完全答對,而且並非多難只是因為大多面試者過於輕視他。

題目如下:

function Foo() {
    getName = function () { alert (1); };
    return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);}

//请写出以下输出结果:
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();

#答案是:

function Foo() {
    getName = function () { alert (1); };
    return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);}

//答案:
Foo.getName();//2
getName();//4
Foo().getName();//1
getName();//1
new Foo.getName();//2
new Foo().getName();//3
new new Foo().getName();//3

此題是我綜合之前的開發經驗以及遇到的JS各種坑匯集而成。此題涉及的知識點眾多,包括變數定義提升、this指標指向、運算子優先權、原型、繼承、全域變數污染、物件屬性及原型屬性優先權等等。

此題包含7小問,分別說下。

第一問

先看此題的上半部做了什麼,先定義了一個叫Foo的函數,之後為Foo建立了一個叫getName的靜態屬性儲存了一個匿名函數,之後為Foo的原型物件新建立了一個叫getName的匿名函數。之後又透過函數變數表達式建立了一個getName的函數,最後再宣告一個叫getName函數。

第一問的 Foo.getName 自然是存取Foo函數上儲存的靜態屬性,自然是2,沒什麼好說的。

第二問

第二問,直接呼叫 getName 函數。既然是直接呼叫就是存取目前上文作用域內的叫getName的函數,所以跟1 2 3都沒什麼關係。此題有無數面試者回答為5。此處有兩個坑,一是變數宣告提升,二是函數表達式。

變數宣告提升

即所有宣告變數或宣告函數都會被提升到目前函數的頂端。

例如下程式碼:

console.log('x' in window);//true
var x;
x = 0;

#程式碼執行時js引擎會將宣告語句提升至程式碼最上方,變成:

var x;
console.log('x' in window);//true
x = 0;

函數表達式

var getName 與 function getName 都是宣告語句,差異在於 var getName 是函數表達式,而 function getName 則是函數宣告。關於JS中的各種函數創建方式可以看 大部分人都會做錯的經典JS閉包面試題 這篇文章有詳細說明。

函數表達式最大的問題,在於js會將此程式碼拆分為兩行程式碼分別執行。

例如下程式碼:

console.log(x);//输出:function x(){}
var x=1;
function x(){}

實際執行的程式碼為,先將 var x=1 分割為 var x; 與 x = 1; 兩行,再將 var x; 和 function x(){} 兩行提升至上方變成:

var x;
function x(){}
console.log(x);
x=1;

#所以最終函數宣告的x覆蓋了變數宣告的x,log輸出為x函數。

同理,原題程式碼最終執行時的是:

function Foo() {
    getName = function () { alert (1); };
    return this;
}
var getName;//只提升变量声明
function getName() { alert (5);}//提升函数声明,覆盖var的声明

Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
getName = function () { alert (4);};//最终的赋值再次覆盖function getName声明

getName();//最终输出4

第三個問

第三問的 Foo().getName(); 先執行了Foo函數,然後呼叫Foo函數的回傳值物件的getName屬性函數。

Foo函數的第一句  getName = function () { alert (1); };  是一個函數賦值語句,注意它沒有var聲明,所以先向當前Foo函數作用域內尋找getName變量,沒有。接著向目前函數作用域上層,也就是外層作用域內尋找是否含有getName變量,找到了,也就是第二問中的alert(4)函數,將此變數的值賦值為 function(){alert(1) }。

這裡其實是將外層作用域內的getName函數修改了。

注意:此處若依然沒有找到會一直向上查找到window對象,若window對像中也沒有getName屬性,就在window對像中創建一個getName變數。

之後Foo函數的回傳值是this,而JS的this問題部落格園中已經有非常多的文章介紹,這裡不再多說。

簡單的講,this的指向是由所在函數的呼叫方式決定的。而此處的直接呼叫方式,this指向window物件。

遂Foo函數回傳的是window對象,相當於執行 window.getName() ,而window中的getName已經被修改為alert(1),所以最終會輸出1

#此處考察了兩個知識點,一個是變數作用域問題,一個是this指向問題。

第四個問

直接呼叫getName函數,相當於 window.getName() ,因為這個變數已經被Foo函數執行時修改了,遂結果與第三問相同,為1

第五問

第五問 new Foo.getName(); ,此處檢視的是js的運算子優先權問題。

js運算子優先權:

很多前端程式設計師經常忽略的一個JavaScript面試題的總結

參考連結:http://www.php.cn/

透過查上表可以得知點(.)的優先權高於new操作,遂相當於是:

new (Foo.getName)();

所以實際上將getName函數作為了建構子來執行,遂彈出2。

第六问

第六问 new Foo().getName() ,首先看运算符优先级括号高于new,实际执行为

(new Foo()).getName()

遂先执行Foo函数,而Foo此时作为构造函数却有返回值,所以这里需要说明下js中的构造函数返回值问题。

构造函数的返回值

在传统语言中,构造函数不应该有返回值,实际执行的返回值就是此构造函数的实例化对象。

而在js中构造函数可以有返回值也可以没有。

1、没有返回值则按照其他语言一样返回实例化对象。

很多前端程式設計師經常忽略的一個JavaScript面試題的總結1

2、若有返回值则检查其返回值是否为引用类型。如果是非引用类型,如基本类型(string,number,boolean,null,undefined)则与无返回值相同,实际返回其实例化对象。

很多前端程式設計師經常忽略的一個JavaScript面試題的總結2

3、若返回值是引用类型,则实际返回值为这个引用类型。

很多前端程式設計師經常忽略的一個JavaScript面試題的總結3

原题中,返回的是this,而this在构造函数中本来就代表当前实例化对象,遂最终Foo函数返回实例化对象。

之后调用实例化对象的getName函数,因为在Foo构造函数中没有为实例化对象添加任何属性,遂到当前对象的原型对象(prototype)中寻找getName,找到了。

遂最终输出3。

第七问

第七问, new new Foo().getName(); 同样是运算符优先级问题。

最终实际执行为:

new ((new Foo()).getName)();

先初始化Foo的实例化对象,然后将其原型上的getName函数作为构造函数再次new。

遂最终结果为3

最后

就答题情况而言,第一问100%都可以回答正确,第二问大概只有50%正确率,第三问能回答正确的就不多了,第四问再正确就非常非常少了。其实此题并没有太多刁钻匪夷所思的用法,都是一些可能会遇到的场景,而大多数人但凡有1年到2年的工作经验都应该完全正确才对。

只能说有一些人太急躁太轻视了,希望大家通过此文了解js一些特性。

并祝愿大家在新的一年找工作面试中胆大心细,发挥出最好的水平,找到一份理想的工作。


以上是很多前端程式設計師經常忽略的一個JavaScript面試題的總結的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
JavaScript數據類型:瀏覽器和nodejs之間是否有區別?JavaScript數據類型:瀏覽器和nodejs之間是否有區別?May 14, 2025 am 12:15 AM

JavaScript核心數據類型在瀏覽器和Node.js中一致,但處理方式和額外類型有所不同。 1)全局對像在瀏覽器中為window,在Node.js中為global。 2)Node.js獨有Buffer對象,用於處理二進制數據。 3)性能和時間處理在兩者間也有差異,需根據環境調整代碼。

JavaScript評論:使用//和 / * * / * / * /JavaScript評論:使用//和 / * * / * / * /May 13, 2025 pm 03:49 PM

JavaScriptusestwotypesofcomments:single-line(//)andmulti-line(//).1)Use//forquicknotesorsingle-lineexplanations.2)Use//forlongerexplanationsorcommentingoutblocksofcode.Commentsshouldexplainthe'why',notthe'what',andbeplacedabovetherelevantcodeforclari

Python vs. JavaScript:開發人員的比較分析Python vs. JavaScript:開發人員的比較分析May 09, 2025 am 12:22 AM

Python和JavaScript的主要區別在於類型系統和應用場景。 1.Python使用動態類型,適合科學計算和數據分析。 2.JavaScript採用弱類型,廣泛用於前端和全棧開發。兩者在異步編程和性能優化上各有優勢,選擇時應根據項目需求決定。

Python vs. JavaScript:選擇合適的工具Python vs. JavaScript:選擇合適的工具May 08, 2025 am 12:10 AM

選擇Python還是JavaScript取決於項目類型:1)數據科學和自動化任務選擇Python;2)前端和全棧開發選擇JavaScript。 Python因其在數據處理和自動化方面的強大庫而備受青睞,而JavaScript則因其在網頁交互和全棧開發中的優勢而不可或缺。

Python和JavaScript:了解每個的優勢Python和JavaScript:了解每個的優勢May 06, 2025 am 12:15 AM

Python和JavaScript各有優勢,選擇取決於項目需求和個人偏好。 1.Python易學,語法簡潔,適用於數據科學和後端開發,但執行速度較慢。 2.JavaScript在前端開發中無處不在,異步編程能力強,Node.js使其適用於全棧開發,但語法可能複雜且易出錯。

JavaScript的核心:它是在C還是C上構建的?JavaScript的核心:它是在C還是C上構建的?May 05, 2025 am 12:07 AM

javascriptisnotbuiltoncorc; sanInterpretedlanguagethatrunsonenginesoftenwritteninc.1)JavascriptwasdesignedAsignedAsalightWeight,drackendedlanguageforwebbrowsers.2)Enginesevolvedfromsimpleterterpretpretpretpretpreterterpretpretpretpretpretpretpretpretpretcompilerers,典型地,替代品。

JavaScript應用程序:從前端到後端JavaScript應用程序:從前端到後端May 04, 2025 am 12:12 AM

JavaScript可用於前端和後端開發。前端通過DOM操作增強用戶體驗,後端通過Node.js處理服務器任務。 1.前端示例:改變網頁文本內容。 2.後端示例:創建Node.js服務器。

Python vs. JavaScript:您應該學到哪種語言?Python vs. JavaScript:您應該學到哪種語言?May 03, 2025 am 12:10 AM

選擇Python還是JavaScript應基於職業發展、學習曲線和生態系統:1)職業發展:Python適合數據科學和後端開發,JavaScript適合前端和全棧開發。 2)學習曲線:Python語法簡潔,適合初學者;JavaScript語法靈活。 3)生態系統:Python有豐富的科學計算庫,JavaScript有強大的前端框架。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能