10個(gè)JavaScript面試??嫉那岸耸謱戭}總結(jié)
1. 實(shí)現(xiàn)一個(gè)簡單的 JavaScript 函數(shù),用于判斷一個(gè)對象是否為空
判斷對象是否為空的函數(shù) 這個(gè)函數(shù)通過遍歷對象的所有屬性來檢查是否有任何實(shí)際定義的鍵。如果在循環(huán)中找到了一個(gè)鍵,則立即返回false,表示對象不為空。如果沒有找到任何鍵,則在循環(huán)結(jié)束后返回true,表示對象為空。
function isEmptyObject(obj) {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
return false;
}
}
return true;
}
2. 手寫數(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è)行為,對原數(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)簡易版的深拷貝
簡易版深拷貝 實(shí)現(xiàn)了一個(gè)遞歸函數(shù),用于復(fù)制給定對象的所有屬性和嵌套對象。當(dāng)遇到非對象或null類型的值時(shí)直接返回,否則創(chuàng)建一個(gè)新的對象并遞歸地復(fù)制原對象的所有屬性。
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)沒有再次調(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)簡易版 Ajax 請求
簡易版Ajax請求 實(shí)現(xiàn)了一個(gè)基于XMLHttpRequest的簡易Ajax請求函數(shù),返回一個(gè)Promise對象。當(dā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è)簡易版的事件委托
實(shí)現(xiàn)事件委托 事件委托是一種優(yōu)化事件處理的方式,通過監(jiān)聽父級元素的事件,然后通過事件對象判斷觸發(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面試常考的前端手寫題總結(jié)的文章就介紹到這了,更多相關(guān)JavaScript常考手寫題內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
仿163填寫郵件地址自動(dòng)顯示下拉(無優(yōu)化)
本框內(nèi)填個(gè)1,這些值都寫在隱藏域了。代碼里可以看到,用戶輸入包含在里面的時(shí)候,可以按ENTER鍵選中.2008-11-11
js創(chuàng)建一個(gè)input數(shù)組并綁定click事件的方法
這篇文章主要介紹了js創(chuàng)建一個(gè)input數(shù)組并綁定click事件的方法,需要的朋友可以參考下2014-06-06
下載站常用的點(diǎn)擊下載地址提示設(shè)hao123為首頁的js代碼
最近很多下載站下載文件的時(shí)候都提示設(shè)置hao123為首頁,這里我們來分享下具體的實(shí)現(xiàn)方法,需要的朋友可以參考下2013-10-10
淺析javascript異步執(zhí)行函數(shù)導(dǎo)致的變量變化問題解決思路
下面小編就為大家?guī)硪黄獪\析javascript異步執(zhí)行函數(shù)導(dǎo)致的變量變化問題解決思路。小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考2016-05-05
Javascript獲取當(dāng)前日期的農(nóng)歷日期代碼
這篇文章主要介紹了利用Javascript獲取當(dāng)前日期的農(nóng)歷日期代碼,很實(shí)用,需要的朋友可以參考下2014-10-10

