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) // 這里重點 : 當 O 嚴格等于 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被當做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)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
新手怎么學JS?JavaScript基礎(chǔ)語法入門要學什么?
這篇文章主要介紹了新手怎么學JS?JavaScript基礎(chǔ)語法入門要學什么?本文給大家介紹一個大致的學習路線和方向,需要的朋友趕緊一起來看看吧2020-03-19- 這篇文章主要介紹了javascript作用域,作用域鏈,閉包的面試題,在一些前端面試中經(jīng)常會問題,今天小編特此整理分享到腳本之家平臺,需要的朋友可以參考下2020-02-21
JavaScript關(guān)于數(shù)組的四道面試題
這篇文章主要介紹了JavaScript關(guān)于數(shù)組的四道面試題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習2019-12-23- 這篇文章主要介紹了11道JS選擇題(聽說第一題就難倒80%的人),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-12-18
- JS 初學者總是對this關(guān)鍵字感到困惑,因為與其他現(xiàn)代編程語言相比,JS 中的這this關(guān)鍵字有點棘手。今天小編給大家?guī)?0個比較流行的JavaScript面試題 ,感興趣的朋友一起2019-07-12
- 這篇文章主要介紹了10個JavaScript筆試題解析,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2020-06-02