5個典型的JavaScript面試題
JavaScript是一門有意思的語言,入門很快,但是想要深入的理解卻并不簡單,比如JavaScript中的原型、面向對象。對當前的Web世界而言,JavaScript是一門你必須精通的語言,因此本文借用一些面試題來回顧一下JavaScript中的典型知識點。
面試題
1. 變量范圍
以下代碼的輸出結果為:
(function() { var a = b = 5; })(); console.log(b); //5 console.log(a); //Error, a is not defined
解答:
在這個立即執行函數表達式(IIFE)中包括兩個賦值操作,其中a使用var關鍵字進行聲明,因此其屬于函數內部的局部變量(僅存在于函數中),相反,b被分配到全局命名空間。
另一個需要注意的是,這里沒有在函數內部使用嚴格模式(use strict;)。如果啟用了嚴格模式,代碼會在輸出b時報錯Uncaught ReferenceError: b is not defined,需要記住的是,嚴格模式要求你顯式的引用全局作用域。因此,你需要寫成:
(function() { 'use strict'; var a = window.b = 5; })(); console.log(b);
2. 創建“native”方法
在String對象上定義一個repeatify方法。該方法接收一個整數作為參數用于指定字符串的重復次數。例如:
console.log('hello'.repeatify(3)); // hellohellohello
解答:
String.prototype.repeatify = String.prototype.repeatify || function(times) { var str = ''; for (var i = 0; i < times; i++) { str += this; } return str; };
這個題目主要測試你對JavaScript中的繼承和prototype屬性的理解。另一個值得關注的點是,在定義該方法前你需要確定該對象中是否已存在你要定義的同名方法。通常,我們使用如下的方式:
String.prototype.repeatify = String.prototype.repeatify || function(times) {/* code here */};
3. 提升 Hoisting
以下代碼的執行結果為:
function test() { console.log(a); // undefined console.log(foo()); // 2 var a = 1; function foo() { return 2; } } test();
回答:
執行結果分別為undefined和2。
在JavaScript中,變量和命名函數都會被提升到函數的頂端,但是對變量而言其初始化操作不會被提升。因此,當打印a的值時,它雖然存在于函數test()中,但其值此刻為undefined,即未被初始化。也就是說,上面的代碼會被轉換成:
function test() { var a; function foo() { return 2; } console.log(a); console.log(foo()); a = 1; } test();
4.this在JavaScript中是如何工作的
下面代碼的執行結果為:
var fullname = 'John Doe'; var obj = { fullname: 'Colin Ihrig', prop: { fullname: 'Aurelio De Rosa', getFullname: function() { return this.fullname; } } }; console.log(obj.prop.getFullname()); // Aurelio De Rosa var test = obj.prop.getFullname; console.log(test()); // John Doe
解答:
上面的代碼打印結果依次為Aurelio De Rosa和John Doe。 原因在于this指向的是函數的執行環境,this取決于其被誰調用了,而不是被誰定義了。
對第一個console.log()語句而言,getFullName()是作為obj.prop對象的一個方法被調用的,因此此時的執行環境應該是這個對象。另一方面,但getFullName()被分配給test變量時,此時的執行環境變成全局對象(window),原因是test是在全局作用域中定義的。因此,此時的this指向的是全局作用域的fullname變量,即John Doe。
5.call()和apply()
修正題目4中存在的問題,使得最后一個console.log()打印出Aurelio De Rosa。
解答:
可以使用call()或者apply()強制切換執行環境,如果你不知道這兩者的區別,可以參考這篇文章。如下:
console.log(test.call(obj.prop)); // 這里使用apply()也是一樣的
JavaScript學習建議
閱讀列表
無論是jQuery,還是當前熱門的AngularJS和ReactJS,都離不開扎實的JavaScript的基礎。2015年有很多值得你學習的JavaScript知識,如ECMAScript6, TypeScript等等,但這一切之前,你一定要看的書肯定應該包括下面幾本:
- JavaScript高級程序設計,第三版,Nicholas.C.Zakas
- JavaScript權威指南,第五版,犀牛書
- JavaScript語言精粹,修訂版,蝴蝶書
聲明
面試題來源于:http://www.sitepoint.com/5-typical-javascript-interview-exercises/
來自:http://wwsun.me/posts/javascript-interview.html