太久沒有面試過了,第一次難免有點緊張,今天遇到的面試問題,大多數都遇到過,卻因為沒有充分準備,而沒有答好,以後一定好好準備才行。
下面記錄一下今天的面試問題,加深印象:
介紹一下JS的資料型別?
簡單型別:
String
、Number
、Boolean
、Null
、Undefined
複雜型別:Object
ES6新增型別:Symbol
(感謝TimeTraveler指出)
&
擴充套件:- null與undefined有什麼區別
答:null
表示一個物件被定義了,值為“空值”,而undefined
表示不存在這個值。
正因為這個原因,所以使用typeof
判斷是,null
返回的是object
,而undefined
返回的是undefined
。(判斷兩者時需要使用===
嚴格判斷) - Boolean型別在進行判斷的時候設定為 0、-0、null、""、false、undefined 或 NaN,則該物件設定為 false。否則設定為 true(即使 value 引數是字串 "false")
- null與undefined有什麼區別
如何通過JS判斷一個陣列?
- instanceof方法
instanceof
運算子是用來測試一個物件是否在其原型鏈原型建構函式的屬性。var arr = []; arr instanceof Array; // true複製程式碼
- constructor方法
constructor
屬性返回對建立此物件的陣列函式的引用,就是返回物件相對應的建構函式。var arr = []; arr.constructor == Array; //true複製程式碼
- 特性判斷法
利用判斷陣列獨有的length
和splice
方法,但是這是不靠譜的,因為物件也能新增方法和屬性。那怎麼辦了,有一個辦法,可以利用陣列的length屬性
沒法列舉來判斷。function isArray(object){ return object && typeof object==='object' && typeof object.length==='number' && typeof object.splice==='function' && //判斷length屬性是否是可列舉的 對於陣列 將得到false !(object.propertyIsEnumerable('length')); }複製程式碼
- 最簡單的方法
這種寫法,是 jQuery 正在使用的,淘寶的 kissy 也是使用這種方式。Object.prototype.toString.call(value) == '[object Array]' // 利用這個方法,可以寫一個返回資料型別的方法 var isType = function (obj) { return Object.prototype.toString.call(obj).slice(8,-1); }複製程式碼
- ES5新增方法isArray()
&var a = new Array(123); var b = new Date(); console.log(Array.isArray(a)); //true console.log(Array.isArray(b)); //false複製程式碼
擴充套件:- 使用
instaceof
和construcor
,被判斷的array
必須是在當前頁面宣告的。比如,一個頁面(父頁面)有一個框架,框架中引用了一個頁面(子頁面),在子頁面中宣告瞭一個array
,並將其賦值給父頁面的一個變數,這時判斷該變數,Array == object.constructor;
會返回false
。 - 最簡單的方法,在IE6下判斷
null
和undefined
,有一些bug,判斷undefined
和null
均為Object
,(並不是bug
,是在ES3的標準下返回的就為Object
)
- 使用
- instanceof方法
談一談
let
與var
的區別?let為ES6新新增申明變數的命令,它類似於
var
,但是有以下不同:let
命令不存在變數提升,如果在let
前使用,會導致報錯- 暫時性死區,如果塊區中存在
let
和const
命令,就會形成封閉作用域 - 不允許重複宣告,因此,不能在函式內部重新宣告引數
map
與forEach
的區別?因為平時基本只用
forEach
,所以這個很尷尬,索性就把新增的陣列方法都刷一遍吧。forEach
方法,是最基本的方法,就是遍歷與迴圈,預設有3個傳參:分別是遍歷的陣列內容item
、陣列索引index
、和當前遍歷陣列Array
。另外,除去第一個必須的回撥函式引數,還可以接受一個上下文引數(改變回撥函式的this指向);並且forEach
不會遍歷空元素。map
方法,基本用法與forEach一致,但是不同的,它會返回一個新的陣列,所以在callback需要有return值,如果沒有,會返回undefined。(從字面理解,map就是對映的意思)filter
方法,用法和map很相似,從字面理解,就是過濾、篩選的意思。但是函式的callback需要返回布林值true
或false
,並且返回值只需要為弱等==
即可。some
方法,對陣列中每一項執行指定函式,如果該函式對任一項返回true
,則返回true
。(一旦遇到true
,就會中斷迴圈,返回true
,類似於||判斷
)every
方法,對陣列中的每一項執行給定函式,如果該函式對每一項返回true
,則返回true
。(一旦遇到false,就會中斷迴圈,返回false
,類似於&&判斷
)indexOf
方法,與字串中的indexOf
類似,返回陣列索引值,如果沒有匹配,則會返回-1
,第二個引數為可選,表示從當前位置開始搜尋。lastIndexOf
方法,與indexOf
相似,只是是從陣列的末尾開始查詢,而第二個引數的預設值是array.length - 1
。reduce
方法,字面意思應該是‘減少’,但是實際是‘遞迴’的意思。實際就是應用一個函式針對陣列的兩個值(從左到右),以減至一個值。它的callback
接收4個引數:之前值(上一次迴圈返回的值)、當前值、索引值以及陣列本身。initialValue
引數可選,表示初始值。reduceRight
方法,與reduce
方法類似,只是從陣列的末尾開始實現。
談一談你理解的函數語言程式設計?
what?函式程式設計就是函式程式設計啊,還有什麼理解??
現在查了一下,才知道,原來沒有那麼簡單!!!
簡單說,"函數語言程式設計"是一種"程式設計正規化"(programming paradigm),也就是如何編寫程式的方法論。
它具有以下特性:閉包和高階函式、惰性計算、遞迴、函式是"第一等公民"、只用"表示式",不用"語句"(都會有返回值)、沒有"副作用"、不修改狀態、引用透明性。
具體的特性代表了什麼,我還要好好研究一下!!談一談箭頭函式與普通函式的區別?
平時用的很爽,但是還真沒有考慮過這個問題!!
- 箭頭函式使得表達更加簡潔。(這個是廢話)
- 函式體內的
this
物件,就是定義時所在的物件,而不是使用時所在的物件。 - 不可以當作建構函式,也就是說,不可以使用
new
命令,否則會丟擲一個錯誤。 - 不可以使用
arguments
物件,該物件在函式體內不存在。如果要用,可以用Rest引數
代替。 - 不可以使用
yield
命令,因此箭頭函式不能用作Generator
函式。
談一談函式中this的指向吧?
this的指向在函式定義的時候是確定不了的,只有函式執行的時候才能確定this到底指向誰,實際上this的最終指向的是那個呼叫它的物件。
《javascript語言精髓》中大概概括了4種呼叫方式:
- 方法呼叫模式
- 函式呼叫模式
- 構造器呼叫模式
- apply/call呼叫模式
特別補充:
- 在構造器呼叫時,如果加入了
return
並且return
了一個物件,this
會指向這個return
的物件。 - 為什麼構造器時
this
會指向new
的物件?var p = new Emp(); // 過程模擬,new關鍵字會建立一個空的物件,然後會自動呼叫一個函式apply方法,將this指向這個空物件,這樣的話函式內部的this就會被這個空的物件替代。 var p = {}; Emp.apply(p); p.__proto__=Emp.prototype;複製程式碼
談一談閉包吧?
「閉包」,是指那些能夠訪問獨立(自由)變數的函式 (變數在本地使用,但定義在一個封閉的作用域中)。換句話說,這些函式可以“記憶”它被建立時候的環境。特性:
- 函式巢狀函式
- 函式內部可以引用外部的引數和變數
- 引數和變數不會被垃圾回收機制回收
非同步程式設計的實現方式?
- 回撥函式:
- 優點:簡單、容易理解
- 缺點:不利於維護,程式碼耦合高
- 事件監聽(採用時間驅動模式,取決於某個事件是否發生):
- 優點:容易理解,可以繫結多個事件,每個事件可以指定多個回撥函式
- 缺點:事件驅動型,流程不夠清晰
- 釋出/訂閱(觀察者模式):
- 類似於事件監聽,但是可以通過‘訊息中心’,瞭解現在有多少釋出者,多少訂閱者。
- Promise物件
- 優點:可以利用then方法,進行鏈式寫法;可以書寫錯誤時的回撥函式;
- 缺點:編寫和理解,相對比較難
- Generator函式
- 優點:函式體內外的資料交換、錯誤處理機制
- 缺點:流程管理不方便
- async函式
- 優點:內建執行器、更好的語義、更廣的適用性、返回的是Promise、結構清晰。
- 缺點:錯誤處理機制
- 回撥函式: