2020年12道高頻JavaScript手寫面試題及答案
JavaScript筆試部分
本文分享 12 道高頻JavaScript的面試題,包含手寫以及常用的正則。
實現(xiàn)防抖函數(shù) (debounce)
防抖函數(shù)原理 : 在事件被觸發(fā)n秒后在執(zhí)行回調(diào),如果在這n秒內(nèi)又被觸發(fā),則重新計時。
那么與節(jié)流函數(shù)的區(qū)別直接看這個動畫實現(xiàn)即可。

手寫簡化版
//防抖函數(shù)
const debounce = (fn,delay)=>{
let timer = null;
return (...args)=>{
clearTimeout(timer);
timer = setTimeout(()=>{
fn.apply(this,args)
},delay);
};
};
適用場景 :
- 按鈕提交場景: 防止多次提交按鈕,只執(zhí)行最后提交的一次
- 服務(wù)端驗證場景 : 表單驗證需要服務(wù)端配合,只執(zhí)行一段連續(xù)的輸入事件的最后一次,還有搜索聯(lián)想詞功能類似
生存環(huán)境請用lodash.debounce
實現(xiàn)節(jié)流函數(shù) (throttle)
防抖函數(shù)原理:規(guī)定在一單位時間內(nèi)。只能觸發(fā)一次函數(shù)。如果這個單位時間內(nèi)觸發(fā)多次函數(shù),只有一次生效。
//手寫簡化版
//節(jié)流函數(shù)
const throttle = (fn,delay = 500) =>{
let flag = true;
return (...args) =>{
if (!flag) return;
flag = false;
setTimeout(() => {
fn.apply(this,args)
},delay);
};
};
適用場景:
- 拖拽場景: 固定時間內(nèi)只執(zhí)行一次,防止超高頻次觸發(fā)位置變動
- 縮放場景: 監(jiān)控瀏覽器resize
- 動畫場景: 避免短時間內(nèi)多次觸發(fā)動畫引起性能問題
深克隆 (deepclone)
簡單版 :
const newObj = JSON.parse(JSON.stringify(oldObj));
局限性 :
1、他無法實現(xiàn)函數(shù)、RegExp等特殊對象的克隆
2、會拋棄對象的constructor,所有的構(gòu)造函數(shù)會指向Object
3、對象有循環(huán)引用,會報錯
實現(xiàn)Event (event bus)
event bus既是node中各個模塊的基石,又是前端組件通信的依賴手段之一,同時涉及了訂閱-發(fā)布設(shè)計模式,是非常重要的基礎(chǔ)。
簡單版:
class EventEmeitter {
constructor(){
this._events = this._events || new Map(); //儲存事件/回調(diào)鍵值對
this._maxListeners = this._maxListeners || 1o;//設(shè)立監(jiān)聽上限
}
}
//觸發(fā)名為type的事件
EventEmeitter.prototype.emit = function(type,...args){
let hander;
//從儲存事件鍵值對的this._events中獲取對應(yīng)事件回調(diào)函數(shù)
handler = this._events.get(type);
if (args.length > 0) {
hander.apply(this,args);
}else{
handler.call(this);
}
return true;
};
//監(jiān)聽名為type事件
EventEmeitter.prototype.addListener = function(type,fn) {
//將type事件以及對應(yīng)的fn函數(shù)放入this._events中儲存
if (!this._events.get(type)) {
this._events.set(type,fn);
}
};
實現(xiàn)instanceOf
//模擬 instanceof
function instance_of(L,R){
var O = R.prototype;//取 R 的顯示原型
L = L.__proto__;//取 L 的隱式原型
while (true) {
if (L === null) return false;
if (O === L)
// 這里重點 : 當(dāng) O 嚴(yán)格等于 L 時,返回 true
return true;
L = L.__proto__;
}
}
模擬new
new操作符做了這些事:
- 他創(chuàng)建了一個全新的對象
- 他會被執(zhí)行[[Prototype]] (也就是__proto__) 鏈接
- 它使this指向新創(chuàng)建的對象
- 通過new創(chuàng)建的每個對象將最終被[[Prototype]]鏈接到這個函數(shù)的prototype對象上
- 如果函數(shù)沒有返回對象類型Object(包含F(xiàn)unction,Array,Date,RegExg,Error),那么new表達式中的函數(shù)調(diào)用將返回對象引用
// objectFactory(name,'cxk','18')
function objectFactory(){
const obj = new object();
const Constructor = [].shift.call(arguments);
obj.__proto__ = Constructor.prototype;
const ret = Constructor.apply(obj,arguments);
return typeof ret === "object" ? ret : obj;
}
實現(xiàn)一個call
call做了什么 :
- 將函數(shù)設(shè)為對象的屬性
- 執(zhí)行&刪除這個函數(shù)
- 指定this到函數(shù)并傳人給定參數(shù)執(zhí)行函數(shù)
- 如果不傳人參數(shù),默認指向為 window
//模擬 call bar.mycall(null);
//實現(xiàn)一個call方法;
Function.prototype.myCall = function(context){
//此處沒有考慮context非object情況
context.fn = this;
let args = [];
for (let i = 1,len = arguments.length,i < len; i++){
args.push(arguments[i]);
}
context.fn(...args);
let result = context.fn(...args);
delete context.fn;
return result;
};
實現(xiàn)apply方法
apply原理與call很相似,不多獒數(shù)
//模擬 apply
Function.prototype.myapply = function(context,arr){
var context = Object(context) || window;
context.fn = this;
var result;
if (!arr){
result = context.fn();
}else{
var args = [];
for (var i = 0,len = arr.length;i < len; i++){
args.push("arr["+ i +"]");
}
result = eval("context.fn("+ args + ")");
}
delete context.fn;
return result;
}
實現(xiàn)bind
實現(xiàn)bind要做什么
- 返回一個函數(shù),綁定this,傳遞預(yù)置參數(shù)
- bind返回的函數(shù)可以作為構(gòu)造函數(shù)使用。故作為構(gòu)造函數(shù)時應(yīng)使得this失效,但是傳人的參數(shù)依然有效
// mdn的實現(xiàn)
if (!Function.prototype.bind) {
Function.prototype.bind = function(oThis) {
if (typeof this !== 'function') {
// closest thing possible to the ECMAScript 5
// internal IsCallable function
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function() {},
fBound = function() {
// this instanceof fBound === true時,說明返回的fBound被當(dāng)做new的構(gòu)造函數(shù)調(diào)用
return fToBind.apply(this instanceof fBound
? this
: oThis,
// 獲取調(diào)用時(fBound)的傳參.bind 返回的函數(shù)入?yún)⑼沁@么傳遞的
aArgs.concat(Array.prototype.slice.call(arguments)));
};
// 維護原型關(guān)系
if (this.prototype) {
}
// 下行的代碼使fBound.prototype是fNOP的實例,因此
// 返回的fBound若作為new的構(gòu)造函數(shù),new生成的新對象作為this傳入fBound,新對象的__proto__就是fNOP的實例
fBound.prototype = new fNOP();
return fBound;
};
}
詳解請移步JavaScript深入之bind的模擬實現(xiàn) #12
模擬Object.create
Object.create()方法創(chuàng)建一個新對象,使用現(xiàn)有的對象來提供新創(chuàng)建的對象的__proto__。
// 模擬 Object.create
function create(proto) {
function F() {}
F.prototype = proto;
return new F();
}
模擬Object.create
Object.create() 方法創(chuàng)建一個新對象,使用現(xiàn)有的對象來提供新創(chuàng)建的對象的__proto__。
// 模擬 object.create
function create(proto){
function F(){
F.prototype = proto;
return new F();
}
}
解析 URL Params為對象
let url = 'http://www.domain.com/?user=anonymous&id=123&id=456&city=%E5%8C%97%E4%BA%AC&enabled';
parseParam(url)
/* 結(jié)果
{ user: 'anonymous',
id: [ 123, 456 ], // 重復(fù)出現(xiàn)的 key 要組裝成數(shù)組,能被轉(zhuǎn)成數(shù)字的就轉(zhuǎn)成數(shù)字類型
city: '北京', // 中文需解碼
enabled: true, // 未指定值得 key 約定為 true
}
*/
轉(zhuǎn)化為駝峰命名
var s1 = "get-element-by-id" //轉(zhuǎn)化為 getElementById
var f = function(s){
return s.replace(/-\w/g,function(x){
return x.slice(1).toUpperCase();
})
}
本文主要是一些基礎(chǔ)知識,希望能幫助那些基礎(chǔ)不太好的同行們。加油~~~~~~
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
新手怎么學(xué)JS?JavaScript基礎(chǔ)語法入門要學(xué)什么?
這篇文章主要介紹了新手怎么學(xué)JS?JavaScript基礎(chǔ)語法入門要學(xué)什么?本文給大家介紹一個大致的學(xué)習(xí)路線和方向,需要的朋友趕緊一起來看看吧2020-03-19
這篇文章主要介紹了javascript作用域,作用域鏈,閉包的面試題,在一些前端面試中經(jīng)常會問題,今天小編特此整理分享到腳本之家平臺,需要的朋友可以參考下2020-02-21JavaScript關(guān)于數(shù)組的四道面試題
這篇文章主要介紹了JavaScript關(guān)于數(shù)組的四道面試題,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)2019-12-23
這篇文章主要介紹了11道JS選擇題(聽說第一題就難倒80%的人),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-12-18
JS 初學(xué)者總是對this關(guān)鍵字感到困惑,因為與其他現(xiàn)代編程語言相比,JS 中的這this關(guān)鍵字有點棘手。今天小編給大家?guī)?0個比較流行的JavaScript面試題 ,感興趣的朋友一起2019-07-12- 這篇文章主要介紹了10個JavaScript筆試題解析,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2020-06-02




