10個(gè)JavaScript面試??嫉那岸耸謱?xiě)題總結(jié)
1. 實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 JavaScript 函數(shù),用于判斷一個(gè)對(duì)象是否為空
判斷對(duì)象是否為空的函數(shù) 這個(gè)函數(shù)通過(guò)遍歷對(duì)象的所有屬性來(lái)檢查是否有任何實(shí)際定義的鍵。如果在循環(huán)中找到了一個(gè)鍵,則立即返回false,表示對(duì)象不為空。如果沒(méi)有找到任何鍵,則在循環(huán)結(jié)束后返回true,表示對(duì)象為空。
function isEmptyObject(obj) { for (var key in obj) { if (obj.hasOwnProperty(key)) { return false; } } return true; }
2. 手寫(xiě)數(shù)組去重
數(shù)組去重 第一個(gè)實(shí)現(xiàn)是使用傳統(tǒng)的方法,創(chuàng)建一個(gè)新的數(shù)組,并利用indexOf方法檢查當(dāng)前元素是否已存在于新數(shù)組中,不存在則添加進(jìn)去。 第二個(gè)實(shí)現(xiàn)利用了ES6中的Set數(shù)據(jù)結(jié)構(gòu),它不允許重復(fù)值,所以可以直接將數(shù)組轉(zhuǎn)換為Set再轉(zhuǎn)回?cái)?shù)組達(dá)到去重效果。
function unique(arr) { let res = []; for(let i = 0; i < arr.length; i++) { if(res.indexOf(arr[i]) === -1) { res.push(arr[i]); } } return res; } // 或者使用ES6的新特性Set function uniqueES6(arr) { return [...new Set(arr)]; }
3. 實(shí)現(xiàn)bind函數(shù)
實(shí)現(xiàn)bind函數(shù) JavaScript中原生的bind函數(shù)可以創(chuàng)建一個(gè)新的函數(shù),在調(diào)用時(shí)設(shè)置其this上下文并傳遞預(yù)設(shè)參數(shù)。這里的實(shí)現(xiàn)同樣創(chuàng)建了一個(gè)新的函數(shù),并在其內(nèi)部調(diào)用了原函數(shù),同時(shí)保證了this指向和傳參的正確性。
Function.prototype.myBind = function(context, ...args) { const self = this; return function(...newArgs) { return self.apply(context, [...args, ...newArgs]); }; };
4. 實(shí)現(xiàn)數(shù)組的map方法
實(shí)現(xiàn)map方法 Array.prototype.map() 方法創(chuàng)建一個(gè)新數(shù)組,其結(jié)果是該數(shù)組中的每個(gè)元素都調(diào)用一個(gè)提供的函數(shù)后返回的結(jié)果。這里我們模擬了這個(gè)行為,對(duì)原數(shù)組進(jìn)行遍歷,并將回調(diào)函數(shù)應(yīng)用于每個(gè)元素,然后將結(jié)果推入新數(shù)組。
Array.prototype.myMap = function(callback, thisArg) { const newArray = []; for (let i = 0; i < this.length; i++) { newArray.push(callback.call(thisArg, this[i], i, this)); } return newArray; };
5. 實(shí)現(xiàn)簡(jiǎn)易版的深拷貝
簡(jiǎn)易版深拷貝 實(shí)現(xiàn)了一個(gè)遞歸函數(shù),用于復(fù)制給定對(duì)象的所有屬性和嵌套對(duì)象。當(dāng)遇到非對(duì)象或null類型的值時(shí)直接返回,否則創(chuàng)建一個(gè)新的對(duì)象并遞歸地復(fù)制原對(duì)象的所有屬性。
function deepClone(obj) { if (typeof obj !== 'object' || obj === null) { return obj; } let cloneObj = Array.isArray(obj) ? [] : {}; for(let key in obj) { if (obj.hasOwnProperty(key)) { cloneObj[key] = deepClone(obj[key]); } } return cloneObj; }
6. 實(shí)現(xiàn)防抖函數(shù)(debounce)
防抖函數(shù)(debounce) 防抖函數(shù)用于限制某個(gè)函數(shù)在一定時(shí)間內(nèi)只能執(zhí)行一次。例如在窗口 resize 或輸入框連續(xù)輸入事件中,防止短時(shí)間內(nèi)多次觸發(fā)。這里的實(shí)現(xiàn)是在每次調(diào)用時(shí)清除上一次的延時(shí)任務(wù),然后重新設(shè)置一個(gè)延時(shí)任務(wù),只有在指定時(shí)間間隔內(nèi)沒(méi)有再次調(diào)用時(shí),才會(huì)執(zhí)行原函數(shù)。
function debounce(func, wait) { let timeout; return function(...args) { clearTimeout(timeout); timeout = setTimeout(() => { func.apply(this, args); }, wait); }; }
7. 實(shí)現(xiàn)節(jié)流函數(shù)(throttle)
節(jié)流函數(shù)(throttle) 節(jié)流函數(shù)確保在一定時(shí)間內(nèi),只允許函數(shù)執(zhí)行一次。與防抖不同的是,節(jié)流保證了在持續(xù)觸發(fā)的情況下,至少每隔一定時(shí)間會(huì)執(zhí)行一次函數(shù)。這里的實(shí)現(xiàn)是在觸發(fā)函數(shù)時(shí)記錄上一次執(zhí)行的時(shí)間,如果當(dāng)前時(shí)間與上次執(zhí)行時(shí)間差大于設(shè)定的時(shí)間間隔,則執(zhí)行函數(shù)
function throttle(func, delay) { let prev = Date.now(); return function(...args) { const now = Date.now(); if (now - prev >= delay) { func.apply(this, args); prev = now; } }; }
8. 實(shí)現(xiàn) Promise 的 then 方法
實(shí)現(xiàn)Promise的then方法 Promise的then方法接受兩個(gè)回調(diào)函數(shù)作為參數(shù),分別處理成功和失敗的情況。這里模擬Promise的狀態(tài)機(jī),根據(jù)Promise當(dāng)前狀態(tài)異步執(zhí)行相應(yīng)的回調(diào)函數(shù),并處理回調(diào)返回的新Promise。
MyPromise.prototype.then = function(onFulfilled, onRejected) { let self = this; return new MyPromise((resolve, reject) => { if (self.status === 'fulfilled') { setTimeout(() => { // 異步執(zhí)行 try { let x = onFulfilled(self.value); resolvePromise(x, resolve, reject); } catch(e) { reject(e); } }, 0); } else if (self.status === 'rejected') { setTimeout(() => { try { let x = onRejected(self.reason); resolvePromise(x, resolve, reject); } catch(e) { reject(e); } }, 0); } else { self.onResolvedCallbacks.push(() => { setTimeout(() => { try { let x = onFulfilled(self.value); resolvePromise(x, resolve, reject); } catch(e) { reject(e); } }, 0); }); self.onRejectedCallbacks.push(() => { setTimeout(() => { try { let x = onRejected(self.reason); resolvePromise(x, resolve, reject); } catch(e) { reject(e); } }, 0); }); } }); }; ???????function resolvePromise(value, resolve, reject) { if (value instanceof MyPromise) { value.then(resolve, reject); } else { resolve(value); } }
9. 實(shí)現(xiàn)簡(jiǎn)易版 Ajax 請(qǐng)求
簡(jiǎn)易版Ajax請(qǐng)求 實(shí)現(xiàn)了一個(gè)基于XMLHttpRequest的簡(jiǎn)易Ajax請(qǐng)求函數(shù),返回一個(gè)Promise對(duì)象。當(dāng)請(qǐng)求完成且狀態(tài)碼正常時(shí)解析響應(yīng)內(nèi)容并resolve,否則reject。
function ajax(url, method, data) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open(method, url, true); xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status >= 200 && xhr.status < 300) { resolve(JSON.parse(xhr.responseText)); } else { reject(xhr.statusText); } } }; xhr.onerror = function() { reject(xhr.statusText); }; xhr.send(JSON.stringify(data)); }); }
10. 實(shí)現(xiàn)一個(gè)簡(jiǎn)易版的事件委托
實(shí)現(xiàn)事件委托 事件委托是一種優(yōu)化事件處理的方式,通過(guò)監(jiān)聽(tīng)父級(jí)元素的事件,然后通過(guò)事件對(duì)象判斷觸發(fā)事件的具體子元素,從而減少綁定事件的數(shù)量。在這個(gè)實(shí)現(xiàn)中,當(dāng)父元素接收到事件時(shí),會(huì)向上遍歷事件傳播鏈,查找是否匹配特定選擇器的目標(biāo)元素,如果匹配就執(zhí)行處理器函數(shù)。
function delegateEvent(element, selector, eventType, handler) { element.addEventListener(eventType, function(event) { let target = event.target; while (target && target !== this) { if (target.matches(selector)) { handler.call(target, event); break; } target = target.parentNode; } }); }
到此這篇關(guān)于10個(gè)JavaScript面試??嫉那岸耸謱?xiě)題總結(jié)的文章就介紹到這了,更多相關(guān)JavaScript??际謱?xiě)題內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS學(xué)習(xí)之表格的排序簡(jiǎn)單實(shí)例
下面小編就為大家?guī)?lái)一篇JS學(xué)習(xí)之表格的排序簡(jiǎn)單實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧2016-05-05仿163填寫(xiě)郵件地址自動(dòng)顯示下拉(無(wú)優(yōu)化)
本框內(nèi)填個(gè)1,這些值都寫(xiě)在隱藏域了。代碼里可以看到,用戶輸入包含在里面的時(shí)候,可以按ENTER鍵選中.2008-11-11js創(chuàng)建一個(gè)input數(shù)組并綁定click事件的方法
這篇文章主要介紹了js創(chuàng)建一個(gè)input數(shù)組并綁定click事件的方法,需要的朋友可以參考下2014-06-06下載站常用的點(diǎn)擊下載地址提示設(shè)hao123為首頁(yè)的js代碼
最近很多下載站下載文件的時(shí)候都提示設(shè)置hao123為首頁(yè),這里我們來(lái)分享下具體的實(shí)現(xiàn)方法,需要的朋友可以參考下2013-10-10淺析javascript異步執(zhí)行函數(shù)導(dǎo)致的變量變化問(wèn)題解決思路
下面小編就為大家?guī)?lái)一篇淺析javascript異步執(zhí)行函數(shù)導(dǎo)致的變量變化問(wèn)題解決思路。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考2016-05-05Javascript獲取當(dāng)前日期的農(nóng)歷日期代碼
這篇文章主要介紹了利用Javascript獲取當(dāng)前日期的農(nóng)歷日期代碼,很實(shí)用,需要的朋友可以參考下2014-10-10