作為一個勤勞的corder,在大年三十的前一天還留守在公司的最前線。百無聊賴中看到一套關於js的測試題,測試過后發現有些題還是有很大的意義,至少能夠讓我門對js基礎有所重視。本人將每道題的考察點總結了一下,希望能夠幫助還游盪在js門外的同學們,由於本人也是js新手,文中如有不妥望大神們指出,共同進步。
話不多說,直接上題:
1. 下面函數的返回值是?
(function(){ return typeof arguments; })();
A. "object" B. "array" C. "arguments" D. "undefined"
分析:我們知道在函數體內,標識符是arguments是指向實參對象的引用。arguments並不是真正的數組,它是一個實參對象。每個實參對象都包含以數字為索引的一組元素以及length屬性,可以理解它是對象,只是碰巧具有以數字為索引的屬性。既然是對象,typeof arguments返回的是必然是object。
2. 下面函數的結果是?
var f = function g(){ return 23; }; typeof g();
A. "number" B. "undefined" C. "function" D. "Error"
分析:定義一個函數可以是:
1.函數聲明 function 函數名稱 (參數:可選){ 函數體}
2. 函數表達式 function 函數名稱(可選)(參數:可選){ 函數體 }
題目中的定義方式為命名函數表達式,函數名g只能在函數體內部訪問,因此在函數外部執行g()會報錯,結果是D。
如果想進一步了解關於函數命名表達式可以參考本站中湯姆大叔的JavaScript連載系列深入理解JavaScript系列(2):揭秘命名函數表達式。
3. 下面函數的返回值是?
(function(x){ delete x; return x; })(1);
A. 1 B. null C. undefined D. Error
分析:delete可以刪除對象的某些屬性,但是不能刪除arguments對象。因此最終結果仍是1。
4. 下面函數的結果是?
var y = 1, x = y = typeof x; x;
A. 1 B. "number" C. undefined D. "undefined"
分析:該題我們只需要知道 x = y = typeof x的執行順序即可。將上述表達式拆分為兩步:
1. y = typeof x; 2. x = y。
執行 y = typeof x 的時候x還沒有定義,只有typeof一個未定義的變量時會返回"undefined",其他情況均會報錯。所以y = "undefined", x = y = "undefined"。
5. 下面函數的返回值是?
(function f(f){ return typeof f(); })(function(){ return 1; });
A. "function" B. "number" C. Error D. "undefined"
分析:將一個函數作為一個函數的參數,f()返回1,typeof f()必然返回"number"。
6. 下面函數的返回值是?
var foo = { bar: function() { return this.baz; }, baz: 1 }; (function(){ return typeof arguments[0](); })(foo.bar);
A. "object" B. "number" C. "function" D. "undefined"
分析:將foo.bar作為一個函數的參數。一定要看清最后返回的不是arguments[0],而是arguments[0]()。而執行foo.bar( 等同於arguments[0]() )返回的是this.baz,在這里this指向的是arguments對象。arguments對象沒有baz屬性,因此返回undefined。
7. 下面函數的結果是?
var foo = { bar: function(){ return this.baz; }, baz: 1 } typeof (f = foo.bar)();
A. "object" B. "number" C. "function" D. "undefined"
分析:foo.bar 為 function(){ return this.baz },將 foo.bar 賦給變量 f 並執行返回this.baz,此時this指向window,window並沒有一個baz屬性,所以最終返回"undefined"。我們可以做個實驗,如果在定義對象foo之前加入一句window.baz = 100; 最后返回的值就是"number"。說明this當時指向的是window。
8. 下面函數的結果是?
var f = (function f(){ return "1"; }, function g(){ return 2; })(); typeof f;
A. "string" B. "number" C. "function" D. "undefined"
分析:我們先來看一個表達式 f = (1,2); f的值最終是2。然后再看這個題目就比較簡單了,f 最終執行的是括號里的第二個函數,返回的是"number"。
9. 下面函數的結果是?
var x = 1; if (function f(){}) { x += typeof f;
} x;
A. 1 B. "1function" C. NaN D. "1undefined"
分析:將一個函數作為 if 判斷條件,返回的是true。typeof f的值是"function",1 + "function" = "1function"。
10. 下面函數的結果是?
var x = [typeof x, typeof y][1]; typeof typeof x;
A. "number" B. "string" C. "object" D. "undefined"
分析:x = typeof y。由於y未定義,所以返回的是"undefined"。而typeof ("undefined")返回的是string。
11. 下面函數的結果是?
(function(foo){ return typeof foo.bar; })({ foo: { bar: 1 } });
A. "number" B. Error C. "object" D. "undefined"
分析:將{ foo: { bar : 1 } }作為參數傳入函數中,傳入的參數只是一個對象,並沒有將該對象賦給任何一個變量,因此typeof foo.bar返回的是"undefined"。
如果定義var x = { foo: { bar : 1 } },則 x.foo.bar == 1。
12. 下面函數的返回值是?
(function f(){ function f(){ return 1; } return f(); function f(){ return 2; } })();
A. 1 B. Error(e.g. "Too much recursion") C. 2 D. undefined
分析:這個題目涉及到了JS的預解析概念。首先看一下函數的預解析機制:
1、javascript在執行前會進行類似"預解析"的操作:首先會創建一個在當前執行環境下的活動對象,並將那些用var 聲明的變量、定義的函數設置為活動對象的屬性,但是此時這些變量的賦值都是undefined。
2、在javascript解釋執行階段,遇到變量需要解析時,會首先從當前執行環境的活動對象中查找,如果沒有找到而且該執行環境的擁有者有prototype屬性時則會從prototype鏈中查找,否則將會按照作用域鏈查找。遇到var a = …這樣的語句時會給相應的變量進行賦值(注意:變量的賦值是在解釋執行階段完成的,如果在這之前使用變量,它的值會是undefined)。
也就是說雖然function f(){return 2;}放在了return的后邊,但是它在預解析的階段就已經定義好了,最終函數f返回的應該是2。更詳細的關於函數預解析和作用域鏈的知識同樣可以參考山姆大叔的JavaScript連載系列深入理解JavaScript系列(14):作用域鏈(Scope Chain)。
13. 下面代碼的結果是?
function f(){ return f; } new f() instanceof f;
A. true B. false
分析:代碼的第二行是通過new來創建的f的實例,所以可以把f看為一個構造函數,而構造函數中如果有return,則返回的是return的內容。也就是f本身,因此f instanceof f返回的是false,而f instanceof Function返回的是true。
14. 下面代碼的結果是?
with (function(x, undefined){}) length;
A. 1 B. Error C. 2 D. undefined
分析:本人平時很少使用with語句,網上搜了一下關於with的資料。具體解釋如下:
with 語句可以方便地用來引用某個特定對象中已有的屬性,但是不能用來給對象添加屬性。要給對象創建新的屬性,必須明確地引用該對象。
而with(function(x, undefined){}) length; 等同於 function fn(x, undefined){} fn.length。通過測試發現length屬性返回的是函數參數的個數,本例中即為2。
結語:
相信看完本篇文章的同學也發現了js基礎知識的重要性,本站中山姆大叔的JS連載系列個人感覺質量比較高,如果能夠仔細的研讀一遍對個人的JS水平會有不小的提高。最后在新春來臨之際預祝所有的前端同學馬上有Money,成為前端大牛。附上原文地址:http://perfectionkills.com/javascript-quiz/。