javascript
每个前端开发者必会的二十个JavaScript面试题
問題1:JavaScript 中?undefined?和?not defined?的區別
JavaScript 未聲明變量直接使用會拋出異常:var name is not defined,如果沒有處理異常,代碼就停止運行了。
但是,使用typeof undeclared_variable并不會產生異常,會直接返回?undefined。
問題2:下面的代碼輸出什么?
var y = 1; if (function f(){}) {y += typeof f; } console.log(y);正確的答案應該是?1undefined。
JavaScript中if語句求值其實使用eval函數,eval(function f(){})?返回?function f(){}?也就是?true。
下面我們可以把代碼改造下,變成其等效代碼。
var k = 1; if (1) {eval(function foo(){});k += typeof foo; } console.log(k);上面的代碼輸出其實就是?1undefined。為什么那?我們查看下?eval()?說明文檔即可獲得答案
該方法只接受原始字符串作為參數,如果 string 參數不是原始字符串,那么該方法將不作任何改變地返回。
恰恰?function f(){}?語句的返回值是?undefined,所以一切都說通了。
注意上面代碼和以下代碼不同。
var k = 1; if (1) {function foo(){};k += typeof foo; } console.log(k); // output 1function問題3:在JavaScript中創建一個真正的private方法有什么缺點?
每一個對象都會創建一個private方法的方法,這樣很耗費內存
觀察下面代碼
var Employee = function (name, company, salary) {this.name = name || ""; this.company = company || ""; this.salary = salary || 5000; // Private methodvar increaseSalary = function () {this.salary = this.salary + 1000;};// Public methodthis.dispalyIncreasedSalary = function() {increaseSlary();console.log(this.salary);}; };// Create Employee class object var emp1 = new Employee("John","Pluto",3000); // Create Employee class object var emp2 = new Employee("Merry","Pluto",2000); // Create Employee class object var emp3 = new Employee("Ren","Pluto",2500);在這里 emp1,emp2,emp3都有一個increaseSalary私有方法的副本。
所以我們除非必要,非常不推薦使用私有方法。
問題4:JavaScript中什么是閉包?寫出一個例子
老生常談的問題了,閉包是在一個函數里聲明了另外一個函數,并且這個函數訪問了父函數作用域里的變量。
下面給出一個閉包例子,它訪問了三個域的變量
- 它自己作用域的變量
- 父函數作用域的變量
- 全局作用域的變量
輸出很簡單:
outerArg = 7 outerFuncVar = x innerArg = 5 innerFuncVar = y globalVar = abc問題5:寫一個mul函數,使用方法如下。
console.log(mul(2)(3)(4)); // output : 24 console.log(mul(4)(3)(4)); // output : 48答案直接給出:
function mul (x) {return function (y) { // anonymous function return function (z) { // anonymous function return x * y * z; };}; }簡單說明下: mul 返回一個匿名函數,運行這個匿名函數又返回一個匿名函數,最里面的匿名函數可以訪問 x,y,z 進而算出乘積返回即可。
對于JavaScript中的函數一般可以考察如下知識點:
- 函數是一等公民
- 函數可以有屬性,并且能連接到它的構造方法
- 函數可以像一個變量一樣存在內存中
- 函數可以當做參數傳給其他函數
- 函數可以返回其他函數
問題6:JavaScript怎么清空數組?
如
var arrayList = ['a','b','c','d','e','f'];怎么清空?arrayList
方法1
arrayList = [];直接改變arrayList所指向的對象,原對象并不改變。
方法2
arrayList.length = 0;這種方法通過設置length=0 使原數組清除元素。
方法3
arrayList.splice(0, arrayList.length);和方法2相似
問題7:怎么判斷一個object是否是數組(array)?
方法1
使用 Object.prototype.toString 來判斷是否是數組
function isArray(obj){return Object.prototype.toString.call( obj ) === '[object Array]'; }這里使用call來使 toString 中 this 指向 obj。進而完成判斷
方法二
使用 原型鏈 來完成判斷
function isArray(obj){return obj.__proto__ === Array.prototype; }基本思想是利用 實例如果是某個構造函數構造出來的那么 它的?__proto__是指向構造函數的?prototype屬性。
方法3
利用JQuery
function isArray(obj){return $.isArray(obj) }JQuery isArray 的實現其實就是方法1
問題8:下面代碼輸出什么?
var output = (function(x){delete x;return x; })(0);console.log(output);輸出是?0。?delete?操作符是將object的屬性刪去的操作。但是這里的?x?是并不是對象的屬性,?delete?操作符并不能作用。
問題9:下面代碼輸出什么?
var x = 1; var output = (function(){delete x;return x; })();console.log(output);輸出是?1。delete?操作符是將object的屬性刪去的操作。但是這里的?x?是并不是對象的屬性,?delete?操作符并不能作用。
問題10:下面代碼輸出什么?
var x = { foo : 1}; var output = (function(){delete x.foo;return x.foo; })();console.log(output);輸出是?undefined。x雖然是全局變量,但是它是一個object。delete作用在x.foo上,成功的將x.foo刪去。所以返回undefined
問題11:下面代碼輸出什么?
var Employee = {company: 'xyz' } var emp1 = Object.create(Employee); delete emp1.company console.log(emp1.company);輸出是?xyz,這里的 emp1 通過 prototype 繼承了 Employee的 company。emp1自己并沒有company屬性。所以delete操作符的作用是無效的。
問題12:什么是?undefined x 1??
在chrome下執行如下代碼,我們就可以看到undefined x 1的身影。
var trees = ["redwood","bay","cedar","oak","maple"]; delete trees[3]; console.log(trees); 當我們使用 delete 操作符刪除一個數組中的元素,這個元素的位置就會變成一個占位符。打印出來就是undefined x 1。
注意如果我們使用trees[3] === 'undefined × 1'返回的是?false。因為它僅僅是一種打印表示,并不是值變為undefined x 1。
問題13:下面代碼輸出什么?
var trees = ["xyz","xxxx","test","ryan","apple"]; delete trees[3];console.log(trees.length);輸出是5。因為delete操作符并不是影響數組的長度。
問題14:下面代碼輸出什么?
var bar = true; console.log(bar + 0); console.log(bar + "xyz"); console.log(bar + true); console.log(bar + false);輸出是
1 truexyz 2 1下面給出一個加法操作表
- Number + Number -> 加法
- Boolean + Number -> 加法
- Boolean + Boolean -> 加法
- Number + String -> 連接
- String + Boolean -> 連接
- String + String -> 連接
問題15:下面代碼輸出什么?
var z = 1, y = z = typeof y; console.log(y);輸出是?undefined。js中賦值操作結合律是右至左的 ,即從最右邊開始計算值賦值給左邊的變量。
上面代碼等價于
var z = 1 z = typeof y; var y = z; console.log(y);問題16:下面代碼輸出什么?
var foo = function bar(){ return 12; }; typeof bar();輸出是拋出異常,bar is not defined。如果想讓代碼正常運行,需要這樣修改代碼:
var bar = function(){ return 12; }; typeof bar();或者是
function bar(){ return 12; }; typeof bar();明確說明這個下問題
var foo = function bar(){ // foo is visible here // bar is visible hereconsole.log(typeof bar()); // Work here : ) }; // foo is visible here // bar is undefined here問題17:兩種函數聲明有什么區別?
var foo = function(){ // Some code }; function bar(){ // Some code };foo的定義是在運行時。想系統說明這個問題,我們要引入變量提升的這一概念。
我們可以運行下如下代碼看看結果。
console.log(foo) console.log(bar)var foo = function(){ // Some code }; function bar(){ // Some code };輸出為
undefined function bar(){ // Some code };為什么那?為什么 foo 打印出來是 undefined,而 bar打印出來卻是函數?
JavaScript在執行時,會將變量提升。
所以上面代碼JavaScript 引擎在實際執行時按這個順序執行。
// foo bar的定義位置被提升 function bar(){ // Some code }; var foo;console.log(foo) console.log(bar)foo = function(){ // Some code };原代碼的輸出合理解釋了。
問題18:下面代碼輸出什么?
var salary = "1000$";(function () {console.log("Original salary was " + salary);var salary = "5000$";console.log("My New Salary " + salary); })();輸出是
Original salary was undefined My New Salary 5000$這題同樣考察的是變量提升。等價于以下代碼
var salary = "1000$";(function () {var salary ;console.log("Original salary was " + salary);salary = "5000$";console.log("My New Salary " + salary);})();問題19:什么是?instanceof?操作符?下面代碼輸出什么?
function foo(){ return foo; }console.log(new foo() instanceof foo);instanceof操作符用來判斷是否當前對象是特定類的對象。
如
function Animal(){//或者不寫return語句return this; } var dog = new Animal(); dog instanceof Animal // Output : true但是,這里的foo定義為
function foo(){ return foo; }所以
// here bar is pointer to function foo(){return foo}. var bar = new foo();所以?new foo() instanceof foo?返回 false
問題20: 如果我們使用JavaScript的”關聯數組”,我們怎么計算”關聯數組”的長度?
var counterArray = {A : 3,B : 4 }; counterArray["C"] = 1;其實答案很簡單,直接計算key的數量就可以了。
Object.keys(counterArray).length // Output 3面試題參考自:?21 Essential JavaScript Interview Questions | Codementor
本文給出的面試題答案只是很多合理答案中的幾個,可能會不全面,歡迎大家補充
from:?http://developer.51cto.com/art/201703/535487.htm
總結
以上是生活随笔為你收集整理的每个前端开发者必会的二十个JavaScript面试题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2017年你不能错过的Java类库
- 下一篇: 我眼中的JavaScript函数式编程