最近把常見的面試手寫題還有我本身面試碰到的總結了一下,話很少說,直接看代碼:javascript
Function.prototype.bind = function (_this, ...arg) {
var self = this;
return function () {
return self.apply(ins, ...arg)
}
};
複製代碼
class EventEmitter {
constructor() {
this.listeners = {};
}
on(type, listener) {
let listeners = this.listeners[type];
if (listeners === undefined) {
listeners = [listener]
} else {
listeners.push(listener)
}
}
off(type, listener) {
let listeners = this.listeners[type];
if (listeners === undefined || listeners.length === 0) {
return
} else {
for (let index = 0; index < listeners.length; index++) {
var curListener = listeners[index];
if (curListener === listener) {
listeners.splice(index, 1)
}
}
}
}
emit(type, ...arg) {
let listeners = this.listeners[type];
if (listeners === undefined || listeners.length === 0) {
return
} else {
for (let index = 0; index < listeners.length; index++) {
var curListener = listeners[index];
curListener(...arg)
}
}
}
}
複製代碼
(function (window) {
var id = 0;
function jsonP(options) {
if (!options) return;
id++;
var scriptTag = document.createElement('script'),
container = document.getElementsByTagName('head')[0],
url = options.url,
data = options.data || {},
callback = options.callback,
funcName = `jsonP${id}`,
params = [];
data['callback'] = funcName;
for (var i in data) {
params.push(`${i}=${data[i]}`)
};
window[funcName] = function (res) {
callback && callback(res);
container.removeChild(scriptTag);
delete window[funcName];
}
url += url.indexOf('?') > 0 ? '?' : '&';
url += ary.join('&');
scriptTag.type = 'text/javascript';
scriptTag.src = url;
container.appendChild(scriptTag);
};
window.jsonP = jsonP;
})(window)
複製代碼
class Koa {
constructor() {
this.middleWare = []
}
use(fn) {
this.middleWare.push(fn);
return this
}
listen() {
// 省去啓動服務的步驟,直接讓middleWare開始運行
return compose(this.middleWare)({});
}
}
function compose(middleWare) {
return function (ctx) {
let index = -1;
function next(i) {
index = i;
if (index === middleWare.length) return Promise.resolve()
let fn = middleWare[index];
return Promise.resolve(fn(ctx, () => next(i + 1)));
};
next(0);
}
}
module.exports = Koa;
複製代碼
function lazyLoad(src) {
return new Promise((resolve, reject) => {
let img = new Image();
img.onload = function (ev) {
resolve(ev)
};
img.onerror = function (ev) {
reject(ev)
};
img.src = src;
})
}
複製代碼
function promisify(fn) {
return function (...arg) {
return new Promise(function (resolve, reject) {
try {
res = fn(...arg, (err, ...data) => {
if (err) {
reject(err)
} else {
if (data.length > 1) {
resolve([...arg])
} else {
resolve(data[0])
}
}
})
} catch (err) {
reject(err)
}
})
}
}
複製代碼
// 冒泡排序
function bubbleSort(ary) {
for (var i = 0; i < ary.length; i++) {
for (var j = 0; j < ary.length - i - 1; j++) {
if (ary[j + 1] < ary[j]) {
var temp = ary[j];
ary[j] = ary[j + 1];
ary[j + 1] = temp;
}
}
};
return ary
}
// 快速排序
function quickSort(ary) {
if (ary.length <= 1) return ary
var mid = Math.floor(ary.length / 2);
var midItem = ary.splice(mid, 1)[0];
var leftAry = [];
var rightAry = [];
for (var i = 0; i < ary.length; i++) {
var cur = ary[i];
if (cur >= midItem) {
rightAry.push(cur)
} else {
leftAry.push(cur)
}
};
return quickSort(leftAry).concat([midItem], quickSort(rightAry))
}
複製代碼
const input = document.getElementById('id');
const obj = { val: '' };
Object.defineProperty(obj, 'val', {
get() {
return input.value
},
set(val) {
input.value = value
}
});
input.oninput = function (ev) {
const val = ev.target.value;
obj.val = val;
}
複製代碼
class Promise {
constructor(excutor) {
this.value = null;
this.reason = null;
this.status = 'pending';
this.onFullfilledCallback = [];
this.onRejectedCallback = [];
const resolve = (value) => {
if (this.status === 'pending') {
this.value = value;
this.status = 'resolved';
this.onFullfilledCallback.forEach(fn => {
fn(this.value);
})
}
};
const reject = (reason) => {
if (this.status === 'pending') {
this.reason = reason;
this.status = 'rejected';
this.onRejectedCallback.forEach(fn => {
fn(this.reason)
})
}
}
try {
excutor(resolve, reject)
} catch (err) {
reject(err)
}
}
then(onFullfilled, onRejected) {
onFullfilled = typeof onFullfilled === 'function' ? onFullfilled : val => val;
onRejected = typeof onRejected === 'function' ? onRejected : reason => reason;
return new Promise((resolve, reject) => {
if (this.status === 'resolved') {
setTimeout(() => {
try {
let res = onFullfilled(this.value);
resolve(res)
} catch (err) {
reject(err)
}
});
};
if (this.status === 'rejected') {
setTimeout(() => {
try {
let res = onRejected(this.reason);
resolve(res)
} catch (err) {
reject(err)
}
});
}
if (this.status === 'pending') {
this.onFullfilledCallback.push(() => {
setTimeout(() => {
try {
let res = onFullfilled(this.value);
resolve(res)
} catch (err) {
reject(err)
}
});
});
this.onRejectedCallback.push(() => {
setTimeout(() => {
try{
let res = onRejected(this.reason);
resolve(res)
} catch(err){
reject(err)
}
});
})
}
})
}
};
複製代碼
// 手寫字符串split方法
function split(str, separator) {
var res = [];
if (!separator) {
for (var i = 0; i < str.length; i++) {
res.push(str[i])
}
};
if (typeof separator === 'string' || Object.prototype.toString.call(separator) === '[object RegExp]') {
var newReg = separator.global ? separator : new RegExp(separator, 'g');
var startIndex = 0;
var flag = true;
while (flag) {
var resAry = newReg.exec(str);
if (resAry === null) {
if (!startIndex) {
return [str]
} else {
res.push(str.slice(startIndex));
flag = false;
}
} else {
var endIndex = resAry.index;
var execLength = resAry[0].length;
res.push(str.slice(startIndex, endIndex));
flag = true;
startIndex = endIndex + execLength;
}
}
}
return res
}
console.log(split('aa xb xbx1c x1cx1 dx1edede', 'x1'));
複製代碼
function findMax(str) {
var obj = {};
for (var i in str) {
var cur = str[i];
if (obj[cur]) {
obj[cur] = obj[cur] + 1;
} else {
obj[cur] = 1;
}
};
var maxStr = '';
var maxNum = 0;
for (var key in obj) {
if (obj[key] > maxNum) {
maxNum = obj[key];
maxStr = key;
} else if (obj[key] === maxNum) {
maxStr += key
}
};
return { maxNum, maxStr }
};
複製代碼
function unique(ary) {
let obj = {};
for (let i = 0; i < ary.length; i++) {
const item = ary[i];
if (obj[item]) {
ary.splice(i, 1);
i--;
} else {
obj[item] = item;
}
};
return ary
};
function unique2(ary) {
let res = []
for (let i = 0; i < ary.length; i++) {
const item = ary[i];
if (res.indexOf(item) > -1) {
ary.splice(i, 1);
i--;
} else {
res.push(item)
}
}
return res
}
function unique3(ary) {
return [...new Set(ary)]
}
console.log(unique3([1, 2, 3, 4, 4, 2, 5]));
複製代碼
function flat1(ary) {
return JSON.parse('[' + JSON.stringify(ary).replace(/\[|]/g, '') + ']')
}
function flat2(ary) {
while (ary.some(item => Array.isArray(item))) {
ary = [].concat(...ary)
};
return ary
}
複製代碼
class Stack {
constructor() {
this.items = []
}
push(item){
this.items.push(item)
}
pop(){
return this.items.pop();
}
clear(){
this.items = []
}
get size (){
return this.items.length
}
get isEmpty(){
return this.items.length === 0
}
}
複製代碼
class Queue {
constructor(){
this.items = []
}
enqueue(items){
this.items.push(items)
}
empty(){
this.items = [];
}
dequeue(){
return this.items.shift();
}
get length(){
return this.items.length;
}
get isEmpty(){
return this.items.length === 0;
}
}
複製代碼
// deepCopy
function deepCopy1(obj) {
return JSON.parse(JSON.stringify(obj))
}
function deepCopy2(obj) {
var res;
if (Object.prototype.toString.call(obj) === '[object Array]') {
res = []
} else {
res = {}
};
if (typeof obj !== 'object') {
return
} else {
for (var i in obj) {
var cur = obj[i];
if (typeof cur === 'object') {
res[i] = deepCopy2(cur)
} else {
res[i] = cur
}
}
};
return res
}
複製代碼
function reverseStr1(str) {
return str.split('').reverse().join('');
}
function reverseStr2(str2) {
var res = '';
for (var i = str2.length - 1; i > -1; i--) {
res += str2[i]
};
return res
}
複製代碼
const debounce = (fn, time) => {
let timer;
return function (...arg) {
let that = this;
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(that, [...arg])
}, time);
}
}
const throttle = (fn, time) => {
let startTime = 0;
return function (...arg) {
let that = this;
let curTime = new Date();
if (curTime - startTime >= time) {
fn.apply(that, [...arg]);
startTime = curTime
}
}
}
複製代碼
function inherits(constructor, superConstructor) {
constructor.prototype = Object.create(superConstructor.prototype)
// node中 使用Object.setPrototypeOf(constructor, superConstructor)
}
複製代碼