摘要:如果構造函數返回了一個對象,那么這個對象會取代整個出來的結果。如果構造函數沒有返回對象,那么出來的結果為步驟創建的對象,一般情況下構造函數不返回任何值,不過用戶如果想覆蓋這個返回值,可以自己選擇返回一個普通對象來覆蓋。
前端工程師有時候面試時會遇到一類面試官,他們問的問題對于語言本身非常較真兒,往往不是候選人可能期待的面向實際的問題(有些候選人強調能干活就行,至于知不知道其中緣由是無關痛癢的)。這類題目,雖然沒有邏輯,但某種程度說,確實考察了候選人對于javascript這門語言的理解。
突然想到這個話題是無聊在翻自己的Github,看看以前都寫過什么丑貨。然后翻到了這篇解釋Javascript quiz的文章quiz-legend,反正沒事兒,就想搬過來供大家學習、理解、背誦、批判。
問題一(function(){ return typeof arguments;//"object" })();
arguments是一個Array-like對象,對應的就是傳入函數的參數列表。你可以在任何函數中直接使用該變量。
typeof操作符只會返回string類型的結果。參照如下列表可知對應不同數據,typeof返回的值都是什么:
類型 | 結果 |
---|---|
undefined | "undefined" |
null | "object" |
Boolean | "boolean" |
Number | "number" |
String | "string" |
Symbol (new in ECMAScript 2015) | "symbol" |
Host object (provided by the JS environment) | Implementation-dependent |
Function object (implements [[Call]] in ECMA-262 terms) | "function" |
Any other object | "object" |
問題二由此我們推斷出,typeof arguments是object
var f = function g(){ return 23; }; typeof g();//報錯
這是一個名字是g的function expression,然后又被賦值給了變量f。
這里的函數名g和被其賦值的變量f有如下差異:
函數名g不能變動,而變量f可以被重新賦值
函數名g只能在函數體內部被使用,試圖在函數外部使用g會報錯的
問題三(function(x){ delete x; return x;//1 })(1);
delete操作符可以從對象中刪除屬性,正確用法如下:
delete object.property delete object["property"]
delete操作符只能作用在對象的屬性上,對變量和函數名無效。也就是說delete x是沒有意義的。
問題四你最好也知道,delete是不會直接釋放內存的,她只是間接的中斷對象引用
var y = 1, x = y = typeof x; x;//"undefined"
我們試圖分解上述代碼成下面兩步:
var y = 1; //step 1 var x = y = typeof x; //step 2
第一步應該沒有異議,我們直接看第二步
賦值表達式從右向左執行
y被重新賦值為typeof x的結果,也就是undefined
x被賦值為右邊表達式(y = typeof x)的結果,也就是undefined
問題五(function f(f){ return typeof f();//"number" })(function(){ return 1; });
直接上注釋解釋:
(function f(f){ //這里的f是傳入的參數function(){ return 1; } //執行的結果自然是1 return typeof f(); //所以根據問題一的表格我們知道,typeof 1結果是"number" })(function(){ return 1; });問題六
var foo = { bar: function() { return this.baz; }, baz: 1 }; (function(){ return typeof arguments[0]();//"undefined" })(foo.bar);
這里你可能會誤以為最終結果是number。向函數中傳遞參數可以看作是一種賦值,所以arguments[0]得到是是真正的bar函數的值,而不是foo.bar這個引用,那么自然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"
逗號操作符 對它的每個操作對象求值(從左至右),然后返回最后一個操作對象的值
所以(function f(){ return "1"; }, function g(){ return 2; })的返回值就是函數g,然后執行她,那么結果是2;最后再typeof 2,根據問題一的表格,結果自然是number
問題九var x = 1; if (function f(){}) { x += typeof f; } x;//"1undefined"
這個問題的關鍵點,我們在問題二中談到過,function expression中的函數名f是不能在函數體外部訪問的
問題十var x = [typeof x, typeof y][1]; typeof typeof x;//"string"
因為沒有聲明過變量y,所以typeof y返回"undefined"
將typeof y的結果賦值給x,也就是說x現在是"undefined"
然后typeof x當然是"string"
最后typeof "string"的結果自然還是"string"
問題十一(function(foo){ return typeof foo.bar;//"undefined" })({ foo: { bar: 1 } });
這是個純粹的視覺詭計,上注釋
(function(foo){ //這里的foo,是{ foo: { bar: 1 } },并沒有bar屬性哦。 //bar屬性是在foo.foo下面 //所以這里結果是"undefined" return typeof foo.bar; })({ foo: { bar: 1 } });問題十二
(function f(){ function f(){ return 1; } return f();//2 function f(){ return 2; } })();
通過function declaration聲明的函數甚至可以在聲明之前使用,這種特性我們稱之為hoisting。于是上述代碼其實是這樣被運行環境解釋的:
(function f(){ function f(){ return 1; } function f(){ return 2; } return f(); })();問題十三
function f(){ return f; } new f() instanceof f;//false
當代碼new f()執行時,下面事情將會發生:
一個新對象被創建。它繼承自f.prototype
構造函數f被執行。執行的時候,相應的傳參會被傳入,同時上下文(this)會被指定為這個新實例。new f等同于new f(),只能用在不傳遞任何參數的情況。
如果構造函數返回了一個“對象”,那么這個對象會取代整個new出來的結果。如果構造函數沒有返回對象,那么new出來的結果為步驟1創建的對象,
ps:一般情況下構造函數不返回任何值,不過用戶如果想覆蓋這個返回值,可以自己選擇返回一個普通對象來覆蓋。當然,返回數組也會覆蓋,因為數組也是對象。
于是,我們這里的new f()返回的仍然是函數f本身,而并非他的實例
問題十四with (function(x, undefined){}) length;//2
with語句將某個對象添加的作用域鏈的頂部,如果在statement中有某個未使用命名空間的變量,跟作用域鏈中的某個屬性同名,則這個變量將指向這個屬性值。如果沒有同名的屬性,則將拋出ReferenceError異常。
OK,現在我們來看,由于function(x, undefined){}是一個匿名函數表達式,是函數,就會有length屬性,指的就是函數的參數個數。所以最終結果就是2了
寫在最后有人覺得這些題坑爹,也有人覺得開闊了眼界,見仁見智吧。但有一件事是真的,無論你是否堅定的實踐派,缺了理論基礎,也鐵定走不遠 - 你永遠不會見到哪個熟練的技術工人突然成了火箭專家。
看文檔、讀標準、結合實踐,才是同志們的決勝之道
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/90846.html
摘要:因為題目是我自己寫的,并不是網上摘的,所以知識點比較基礎,也不全面。即使是面試題,也有人掉坑。小結面試題就是這道,我自己的解決方案也說完了。 大家都知道‘不忘初心,方得始終’,但多少人知道‘初心易得,始終難守’。時代在變化,技術在發展,基礎沒變。學習新技術的時候,不應把基礎落下。 1.前言 因為機緣巧合,讓當了無數次面試者的我,當上了面試官,也和幾個面試者交流過。既然要應對面試者,我就...
摘要:因為題目是我自己寫的,并不是網上摘的,所以知識點比較基礎,也不全面。即使是面試題,也有人掉坑。小結面試題就是這道,我自己的解決方案也說完了。 大家都知道‘不忘初心,方得始終’,但多少人知道‘初心易得,始終難守’。時代在變化,技術在發展,基礎沒變。學習新技術的時候,不應把基礎落下。 1.前言 因為機緣巧合,讓當了無數次面試者的我,當上了面試官,也和幾個面試者交流過。既然要應對面試者,我就...
摘要:因為題目是我自己寫的,并不是網上摘的,所以知識點比較基礎,也不全面。即使是面試題,也有人掉坑。小結面試題就是這道,我自己的解決方案也說完了。 大家都知道‘不忘初心,方得始終’,但多少人知道‘初心易得,始終難守’。時代在變化,技術在發展,基礎沒變。學習新技術的時候,不應把基礎落下。 1.前言 因為機緣巧合,讓當了無數次面試者的我,當上了面試官,也和幾個面試者交流過。既然要應對面試者,我就...
摘要:前言得益于金三銀四,在最近一段時間,面試了一些人,但是符合的寥寥無幾。看到我的面試題自己寫的面試題,自己想的答案。聽人說過一個面試套路面試官問的問題,可能面試官自己都不懂,目的只是為了壓工資,挫士氣。不過我是為了測試面試者是不是真的精通。 技術在不斷的創新,隨著框架,庫,構建工具,打包工具,版本控制工具等操作越來越方便,使用越來越簡單。面對這樣的情況,除了興奮,也要警惕。這些工具使得開...
摘要:但有時候我們希望關閉輸入框的自動完成功能,例如當用戶輸入內容的時候,我們希望使用技術從數據庫搜索并列舉而不是在用戶的歷史記錄中搜索。 以下是我整理的一些HTML的基礎面試體,并自己整理了答案。 1 DOCTYPE有什么作用?標準模式與混雜模式如何區分?它們有何意義? 告訴瀏覽器使用哪個版本的HTML規范來渲染文檔。DOCTYPE不存在或形式不正確會導致HTML文檔以混雜模式呈現。標準模...
閱讀 2755·2019-08-30 15:53
閱讀 521·2019-08-29 17:22
閱讀 1040·2019-08-29 13:10
閱讀 2307·2019-08-26 13:45
閱讀 2751·2019-08-26 10:46
閱讀 3202·2019-08-26 10:45
閱讀 2504·2019-08-26 10:14
閱讀 467·2019-08-23 18:23