14 個(gè)折磨人的 JavaScript 面試題
翻到了這篇解釋Javascript quiz的文章quiz-legend,反正沒事兒,就想搬過來供大家學(xué)習(xí)、理解、背誦、批判。
問題一
(function(){ return typeof arguments;//"object" })();
arguments是一個(gè)Array-like對象,對應(yīng)的就是傳入函數(shù)的參數(shù)列表。你可以在任何函數(shù)中直接使用該變量。
typeof操作符只會返回string類型的結(jié)果。參照如下列表可知對應(yīng)不同數(shù)據(jù),typeof返回的值都是什么:
由此我們推斷出,typeof arguments是object
問題二
var f = function g(){ return 23; }; typeof g();//報(bào)錯(cuò)
這是一個(gè)名字是g的function expression,然后又被賦值給了變量f。
這里的函數(shù)名g和被其賦值的變量f有如下差異:
函數(shù)名g不能變動,而變量f可以被重新賦值
函數(shù)名g只能在函數(shù)體內(nèi)部被使用,試圖在函數(shù)外部使用g會報(bào)錯(cuò)的
問題三
(function(x){ delete x; return x;//1 })(1);
delete操作符可以從對象中刪除屬性,正確用法如下:
delete object.property
delete object['property']
delete操作符只能作用在對象的屬性上,對變量和函數(shù)名無效。也就是說delete x是沒有意義的。
你最好也知道,delete是不會直接釋放內(nèi)存的,她只是間接的中斷對象引用
問題四
var y = 1, x = y = typeof x; x;//"undefined"
我們試圖分解上述代碼成下面兩步:
var y = 1; //step 1
var x = y = typeof x; //step 2
第一步應(yīng)該沒有異議,我們直接看第二步
1.賦值表達(dá)式從右向左執(zhí)行
2.y被重新賦值為typeof x的結(jié)果,也就是undefined
3.x被賦值為右邊表達(dá)式(y = typeof x)的結(jié)果,也就是undefined
問題五
(function f(f){ return typeof f();//"number" })(function(){ return 1; });
直接上注釋解釋:
(function f(f){ //這里的f是傳入的參數(shù)function(){ return 1; } //執(zhí)行的結(jié)果自然是1 return typeof f(); //所以根據(jù)問題一的表格我們知道,typeof 1結(jié)果是"number" })(function(){ return 1; });
問題六
var foo = { bar: function() { return this.baz; }, baz: 1 }; (function(){ return typeof arguments[0]();//"undefined" })(foo.bar);
這里你可能會誤以為最終結(jié)果是number。向函數(shù)中傳遞參數(shù)可以看作是一種賦值,所以arguments[0]得到是是真正的bar函數(shù)的值,而不是foo.bar這個(gè)引用,那么自然this也就不會指向foo,而是window了。
問題七
var foo = { bar: function(){ return this.baz; }, baz: 1 } typeof (f = foo.bar)();//"undefined"
這和上一題是一樣的問題,(f = foo.bar)返回的就是bar的值,而不是其引用,那么this也就指的不是foo了。
問題八
var f = (function f(){ return '1'; }, function g(){ return 2; })(); typeof f;//"number"
逗號操作符 對它的每個(gè)操作對象求值(從左至右),然后返回最后一個(gè)操作對象的值
所以(function f(){ return '1'; }, function g(){ return 2; })的返回值就是函數(shù)g,然后執(zhí)行她,那么結(jié)果是2;最后再typeof 2,根據(jù)問題一的表格,結(jié)果自然是number
問題九
var x = 1; if (function f(){}) { x += typeof f; } x;//"1undefined"
這個(gè)問題的關(guān)鍵點(diǎn),我們在問題二中談到過,function expression中的函數(shù)名f是不能在函數(shù)體外部訪問的
問題十
var x = [typeof x, typeof y][1]; typeof typeof x;//"string" 1.因?yàn)闆]有聲明過變量y,所以typeof y返回"undefined"
2.將typeof y的結(jié)果賦值給x,也就是說x現(xiàn)在是"undefined"
3.然后typeof x當(dāng)然是"string"
4.最后typeof "string"的結(jié)果自然還是"string"
問題十一
(function(foo){ return typeof foo.bar;//"undefined" })({ foo: { bar: 1 } });
這是個(gè)純粹的視覺詭計(jì),上注釋
(function(foo){ //這里的foo,是{ foo: { bar: 1 } },并沒有bar屬性哦。 //bar屬性是在foo.foo下面 //所以這里結(jié)果是"undefined" return typeof foo.bar; })({ foo: { bar: 1 } });
問題十二
(function f(){ function f(){ return 1; } return f();//2 function f(){ return 2; } })();
通過function declaration聲明的函數(shù)甚至可以在聲明之前使用,這種特性我們稱之為hoisting。于是上述代碼其實(shí)是這樣被運(yùn)行環(huán)境解釋的:
(function f(){ function f(){ return 1; } function f(){ return 2; } return f(); })();
問題十三
function f(){ return f; } new f() instanceof f;//false
當(dāng)代碼new f()執(zhí)行時(shí),下面事情將會發(fā)生:
1.一個(gè)新對象被創(chuàng)建。它繼承自f.prototype
2.構(gòu)造函數(shù)f被執(zhí)行。執(zhí)行的時(shí)候,相應(yīng)的傳參會被傳入,同時(shí)上下文(this)會被指定為這個(gè)新實(shí)例。new f等同于new f(),只能用在不傳遞任何參數(shù)的情況。
3.如果構(gòu)造函數(shù)返回了一個(gè)“對象”,那么這個(gè)對象會取代整個(gè)new出來的結(jié)果。如果構(gòu)造函數(shù)沒有返回對象,那么new出來的結(jié)果為步驟1創(chuàng)建的對象,
ps:一般情況下構(gòu)造函數(shù)不返回任何值,不過用戶如果想覆蓋這個(gè)返回值,可以自己選擇返回一個(gè)普通對象來覆蓋。當(dāng)然,返回?cái)?shù)組也會覆蓋,因?yàn)閿?shù)組也是對象。
于是,我們這里的new f()返回的仍然是函數(shù)f本身,而并非他的實(shí)例
問題十四
with (function(x, undefined){}) length;//2
with語句將某個(gè)對象添加的作用域鏈的頂部,如果在statement中有某個(gè)未使用命名空間的變量,跟作用域鏈中的某個(gè)屬性同名,則這個(gè)變量將指向這個(gè)屬性值。如果沒有同名的屬性,則將拋出ReferenceError異常。
OK,現(xiàn)在我們來看,由于function(x, undefined){}是一個(gè)匿名函數(shù)表達(dá)式,是函數(shù),就會有l(wèi)ength屬性,指的就是函數(shù)的參數(shù)個(gè)數(shù)。所以最終結(jié)果就是2了
寫在最后
有人覺得這些題坑爹,也有人覺得開闊了眼界,見仁見智吧。但有一件事是真的,無論你是否堅(jiān)定的實(shí)踐派,缺了理論基礎(chǔ),也鐵定走不遠(yuǎn) - 你永遠(yuǎn)不會見到哪個(gè)熟練的技術(shù)工人突然成了火箭專家。
看文檔、讀標(biāo)準(zhǔn)、結(jié)合實(shí)踐,才是同志們的決勝之道。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 詳解JS中的this、apply、call、bind(經(jīng)典面試題)
- 關(guān)于javascript作用域的常見面試題分享
- 10道典型的JavaScript面試題
- 80%應(yīng)聘者都不及格的JS面試題
- Javascript前端經(jīng)典的面試題及答案
- 一道面試題引發(fā)的對javascript類型轉(zhuǎn)換的思考
- JavaScript中最常見的三個(gè)面試題解析
- JS搜狐面試題分析
- JavaScript面試題(指針、帽子和女朋友)
- 關(guān)于js原型的面試題講解
- JavaScript面試題大全(推薦)
- AngularJS 面試題集錦
- js前端面試題及答案整理(一)
- JS面試題---關(guān)于算法臺階的問題
- 一道優(yōu)雅面試題分析js中fn()和return fn()的區(qū)別
- 一道關(guān)于JavaScript變量作用域的面試題
- 一道常被人輕視的web前端常見面試題(JS)
- 最新Javascript程序員面試試題和解題方法
相關(guān)文章
JS 實(shí)現(xiàn)雙色表格實(shí)現(xiàn)代碼
通過為<tr>元素添加屬性或類型選擇器,再通過CSS設(shè)置可以實(shí)現(xiàn)雙色表格,但如果表格很長,逐個(gè)元素添加可真麻煩。而且這樣的代碼維護(hù)起來不容易。所以比較好的方式是用JS實(shí)現(xiàn)。2009-11-11JS實(shí)現(xiàn)圖片點(diǎn)擊后出現(xiàn)模態(tài)框效果
這篇文章主要介紹了JS實(shí)現(xiàn)圖片點(diǎn)擊后出現(xiàn)模態(tài)框效果,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-05-05JS獲取一個(gè)表單字段中多條數(shù)據(jù)并轉(zhuǎn)化為json格式
這篇文章主要介紹了JS獲取一個(gè)表單字段中多條數(shù)據(jù)并轉(zhuǎn)化為json格式的相關(guān)資料,需要的朋友可以參考下2017-10-10當(dāng)自定義數(shù)據(jù)屬性為json格式字符串時(shí)jQuery的data api問題探討
當(dāng)自定義數(shù)據(jù)屬性是一個(gè) json 格式字符串時(shí),緩存的數(shù)據(jù)如果被修改, 則修改后的數(shù)據(jù)繼續(xù)存在于緩存系統(tǒng)中, 如果不留意,這可能導(dǎo)致一些BUG,接下來將對此問題詳細(xì)概述下2013-02-02JavaScript實(shí)現(xiàn)多叉樹的遞歸遍歷和非遞歸遍歷算法操作示例
這篇文章主要介紹了JavaScript實(shí)現(xiàn)多叉樹的遞歸遍歷和非遞歸遍歷算法,結(jié)合實(shí)例形式詳細(xì)分析了JavaScript多叉樹針對json節(jié)點(diǎn)的遞歸與非遞歸遍歷相關(guān)操作技巧,需要的朋友可以參考下2018-02-029行javascript代碼獲取QQ群成員具體實(shí)現(xiàn)
22 行 JavaScript 代碼實(shí)現(xiàn) QQ 群成員提取器,如果沒有達(dá)到效果可能原因一是QQ版本升級了,二是博客里面的代碼也有些繁瑣2013-10-10一文快速學(xué)會創(chuàng)建uni-app項(xiàng)目并了解pages.json文件
這篇文章主要給大家介紹了如何創(chuàng)建uni-app項(xiàng)目并了解pages.json文件的相關(guān)資料,pages.json文件用來對uni-app進(jìn)行全局配置,決定頁面文件的路徑、窗口樣式、原生的導(dǎo)航欄、底部的原生tabbar等,需要的朋友可以參考下2023-10-10