溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

10道典型的JavaScript面試題

發(fā)布時間:2020-10-01 16:13:28 來源:腳本之家 閱讀:173 作者:風雨后見彩虹 欄目:web開發(fā)

問題1: 作用域(Scope)

考慮以下代碼:

(function() {
 var a = b = 5;
})();
console.log(b);

控制臺(console)會打印出什么?

答案:5

如果 嚴格模式開啟,那么代碼就會報錯 ” Uncaught ReferenceError: b is not defined” 。請記住,如果這是預期的行為,嚴格模式要求你顯式地引用全局作用域。所以,你需要像下面這么寫:

(function() {
 'use strict';
 var a = window.b = 5;
})();
console.log(b);

問題2: 創(chuàng)建 “原生(native)” 方法

在 String 對象上定義一個 repeatify 函數(shù)。這個函數(shù)接受一個整數(shù)參數(shù),來明確字符串需要重復幾次。這個函數(shù)要求字符串重復指定的次數(shù)。舉個例子:

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;
};

在這里,另一個關鍵點是,看你怎樣避免重寫可能已經(jīng)定義了的方法。這可以通過在定義自己的方法之前,檢測方法是否已經(jīng)存在。

String.prototype.repeatify = String.prototype.repeatify || function(times) {/* code here */};

問題3: 變量提升(Hoisting)

執(zhí)行以下代碼的結(jié)果是什么?為什么?

function test() {
 console.log(a);
 console.log(foo());
 var a = 1;
 function foo() {
  return 2;
 }
}
test();

答案:

這段代碼的執(zhí)行結(jié)果是undefined 和 2。

這個結(jié)果的原因是,變量和函數(shù)都被提升(hoisted) 到了函數(shù)體的頂部。因此,當打印變量a時,它雖存在于函數(shù)體(因為a已經(jīng)被聲明),但仍然是undefined。換言之,上面的代碼等同于下面的代碼:

function test() {
 var a;
 function foo() {
  return 2;
 }
 console.log(a);
 console.log(foo());
 a = 1;
} 
test();

問題4: 在javascript中,`this`是如何工作的

以下代碼的結(jié)果是什么?請解釋你的答案。

var fullname = 'John Doe';
var obj = {
 fullname: 'Colin Ihrig',
 prop: {
  fullname: 'Aurelio De Rosa',
  getFullname: function() {
   return this.fullname;
  }
 }
};
console.log(obj.prop.getFullname());
var test = obj.prop.getFullname;
console.log(test());

答案:

這段代碼打印結(jié)果是:Aurelio De Rosa 和 John Doe 。原因是,JavaScript中關鍵字this所引用的是函數(shù)上下文,取決于函數(shù)是如何調(diào)用的,而不是怎么被定義的。

在第一個console.log(),getFullname()是作為obj.prop對象的函數(shù)被調(diào)用。因此,當前的上下文指代后者,并且函數(shù)返回這個對象的fullname屬性。相反,當getFullname()被賦值給test變量時,當前的上下文是全局對象window,這是因為test被隱式地作為全局對象的屬性?;谶@一點,函數(shù)返回window的fullname,在本例中即為第一行代碼設置的。

問題5: call() 和 apply()

修復前一個問題,讓最后一個console.log() 打印輸出Aurelio De Rosa.

答案:

這個問題可以通過運用call()或者apply()方法強制轉(zhuǎn)換上下文環(huán)境。

console.log(test.call(obj.prop));

問題6: 閉包(Closures)

考慮下面的代碼:

var nodes = document.getElementsByTagName('button');
for (var i = 0; i < nodes.length; i++) {
 nodes[i].addEventListener('click', function() {
  console.log('You clicked element #' + i);
 });
}

請問,如果用戶點擊第一個和第四個按鈕的時候,控制臺分別打印的結(jié)果是什么?為什么?

答案:

兩次打印都是nodes.length的值。

問題7: 閉包(Closures)

修復上題的問題,使得點擊第一個按鈕時輸出0,點擊第二個按鈕時輸出1,依此類推。

答案:

有多種辦法可以解決這個問題,下面主要使用兩種方法解決這個問題。

第一個解決方案使用立即執(zhí)行函數(shù)表達式(IIFE)再創(chuàng)建一個閉包,從而得到所期望的i的值。實現(xiàn)此方法的代碼如下:

var nodes = document.getElementsByTagName('button');
for (var i = 0; i < nodes.length; i++) {
 nodes[i].addEventListener('click', (function(i) {
  return function() {
   console.log('You clicked element #' + i);
  }
 })(i));
}

另一個解決方案不使用IIFE,而是將函數(shù)移到循環(huán)的外面。這種方法由下面的代碼實現(xiàn):

function handlerWrapper(i) {
 return function() {
  console.log('You clicked element #' + i);
 }
}
var nodes = document.getElementsByTagName('button');
for (var i = 0; i < nodes.length; i++) {
 nodes[i].addEventListener('click', handlerWrapper(i));
}

問題8:數(shù)據(jù)類型

考慮如下代碼:

console.log(typeof null);
console.log(typeof {});
console.log(typeof []);
console.log(typeof undefined);

答案:

object
object
object
undefined

問題9:事件循環(huán)

下面代碼運行結(jié)果是什么?請解釋。

function printing() {
 console.log(1);
 setTimeout(function() { console.log(2); }, 1000);
 setTimeout(function() { console.log(3); }, 0);
 console.log(4);
}
printing();

答案:

1
4
3
2

想知道為什么輸出順序是這樣的,你需要弄了解setTimeout()做了什么,以及瀏覽器的事件循環(huán)原理。瀏覽器有一個事件循環(huán)用于檢查事件隊列,處理延遲的事件。UI事件(例如,點擊,滾動等),Ajax回調(diào),以及提供給setTimeout()和setInterval()的回調(diào)都會依次被事件循環(huán)處理。因此,當調(diào)用setTimeout()函數(shù)時,即使延遲的時間被設置為0,提供的回調(diào)也會被排隊?;卣{(diào)會呆在隊列中,直到指定的時間用完后,引擎開始執(zhí)行動作(如果它在當前不執(zhí)行其他的動作)。因此,即使setTimeout()回調(diào)被延遲0毫秒,它仍然會被排隊,并且直到函數(shù)中其他非延遲的語句被執(zhí)行完了之后,才會執(zhí)行。

問題10:算法

寫一個isPrime()函數(shù),當其為質(zhì)數(shù)時返回true,否則返回false。

答案:

我認為這是面試中最常見的問題之一。然而,盡管這個問題經(jīng)常出現(xiàn)并且也很簡單,但是從被面試人提供的答案中能很好地看出被面試人的數(shù)學和算法水平。

首先, 因為JavaScript不同于C或者Java,因此你不能信任傳遞來的數(shù)據(jù)類型。如果面試官沒有明確地告訴你,你應該詢問他是否需要做輸入檢查,還是不進行檢查直接寫函數(shù)。嚴格上說,應該對函數(shù)的輸入進行檢查。

第二點要記?。贺摂?shù)不是質(zhì)數(shù)。同樣的,1和0也不是,因此,首先測試這些數(shù)字。此外,2是質(zhì)數(shù)中唯一的偶數(shù)。沒有必要用一個循環(huán)來驗證4,6,8。再則,如果一個數(shù)字不能被2整除,那么它不能被4,6,8等整除。因此,你的循環(huán)必須跳過這些數(shù)字。如果你測試輸入偶數(shù),你的算法將慢2倍(你測試雙倍數(shù)字)??梢圆扇∑渌恍└髦堑膬?yōu)化手段,我這里采用的是適用于大多數(shù)情況的。例如,如果一個數(shù)字不能被5整除,它也不會被5的倍數(shù)整除。所以,沒有必要檢測10,15,20等等。

最后一點,你不需要檢查比輸入數(shù)字的開方還要大的數(shù)字。我感覺人們會遺漏掉這一點,并且也不會因為此而獲得消極的反饋。但是,展示出這一方面的知識會給你額外加分。

現(xiàn)在你具備了這個問題的背景知識,下面是總結(jié)以上所有考慮的解決方案:

function isPrime(number) {
 // If your browser doesn't support the method Number.isInteger of ECMAScript 6,
 // you can implement your own pretty easily
 if (typeof number !== 'number' || !Number.isInteger(number)) {
  // Alternatively you can throw an error.
  return false;
 }
 if (number < 2) {
  return false;
 }
 if (number === 2) {
  return true;
 } else if (number % 2 === 0) {
  return false;
 }
 var squareRoot = Math.sqrt(number);
 for(var i = 3; i <= squareRoot; i += 2) {
  if (number % i === 0) {
   return false;
  }
 }
 return true;
}

以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持億速云!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI