前端面试手撕代码-想入大厂这些必须会

instanceof

function myInstanceof(L,R){var LP = L.__proto__;var RP = R.prototype;while(true){if (LP == null){return false;}if (LP == RP){return true;}LP = LP.__proto__;}
}

call (重要)

Function.prototype.mycall = function(context){if (typeof this != 'function'){throw new TypeError("类型不正确")}context = context || windowcontext.fn = this// 为什么从1开始截取?第一个参数不要了吗?// call的第一个参数是this指向的对象,并不是实际传入的参数let args = Array.from(arguments).slice(1)let res = context.fn(...args)delete context.fnreturn res
}

apply (重要)

Function.prototype.myApply = function(context){if (typeof this != 'function'){throw new TypeError('类型错误')}context = context || windowcontext.fn = thislet resif (arguments[1]){res = context.fn(...arguments[1])}else{res = context.fn()}delete context.fnreturn res;
}

bind (重要)

Function.prototype.bind = function(context){if (typeof this != 'function'){throw new TypeError('类型错误')}let _this = this// 这里用Array.prototype.slice.call是因为arguments是一个类数组,本身不存在slice方法,// 因此通过Array.prototype.slice来截取。// 由于截取后成了一个新数组,需要调用call将this指向原来的arguments并从1开始截取let args = Array.prototype.slice.call(arguments,1)return function F(){// 闭包,这里的this是调用闭包函数的对象,跟前面的this不同if(this instanceof F){return new _this(...args,...arguments)}else{return _this.apply(context,args.concat(...arguments))}}
}

new

function myNew(fn,...args){let obj = {}obj.__proto__ = fn.prototypelet res = fn.apply(obj,args)// 这里的instanceof如何理解?// 其实就是看res是不是undefined或者null,如果是就返回新对象,不是就返回数值return res instanceof Object ? res : obj
}

浅拷贝和深拷贝 (重要)

var obj = {a: 1,b: {c: 2,h: '123',d: {e: 3,i: [1, 2, 3],f: {g: 4}}}
}
// 浅拷贝
var newObj = {...obj
}
console.log(newObj);
var newObj2 = Object.assign({}, obj)
console.log(newObj2);function copy(obj) {let newObj = {}for (let o in obj) {newObj[o] = obj[o]}return newObj
}
var newObj3 = copy(obj)
console.log(newObj3);// 深拷贝
function isObject(obj){
// 解释一下什么是 Object.prototype.toString.call
// 一种获取对象类型的方式,实际上是调用了Object.prototype.toString方法,并将其this值设置为要检查类型的对象
// toString方法会返回一个表示对象类型的字符串。
// 但这个方法并不能判断自定义类型return Object.prototype.toString.call(obj) === '[object Object]' || Object.prototype.toString.call(obj) === '[object Array]'
}
function deepCopy(obj, map = new Map()){// 如果是基本数据类型,直接返回if (!isObject(obj)) return obj;// 如果map中已经存在了,直接返回map中的if (map.has(obj)) return map.get(obj)let newObj = Array.isArray(obj) ? [] : {}map.set(obj,newObj)for(let o in obj){if (isObject(obj[o])){// 一个递归newObj[o] = deepCopy(obj[o], map)}else{newObj[o] = obj[o]}}return newObj
}
var deepNewObj = deepCopy(obj)
console.log(deepNewObj);
var deepNewObj2 = JSON.parse(JSON.stringify(obj))
console.log(deepNewObj2);

实现promise (重要)

class Promise {constructor(executor) {this.state = 'pending'this.reason = undefinedthis.value = undefinedthis.success = []this.faild = []let resolve = function (value) {if (this.state == 'pending') {this.state = 'fulfilled'this.value = this.valuethis.success.forEach(call => {call()});}}let reject = function (reason) {if (this.state == 'pending') {this.state = 'reject'this.reason = reasonthis.faild.forEach(call => call())}}try {executor(resolve, reject)} catch (error) {reject(error)}}then(onResolve, onReject) {if (this.state == 'fulfilled') {onResolve(this.value)} else if (this.state == 'reject') {onReject(this.reason)} else {this.success.push(() => onResolve(this.value))this.faild.push(() => onReject(this.reason))}}
}Promise.all = function (promises) {let res = []let count = 0return new Promise((resolve, reject) => {for (let i = 0; i < promises.length; i++) {promises[i].then(ans => {res[i] = anscount++if (count == promises.length) {resolve(res)}}, reason => {reject(reason)})}})
}Promise.race = function (promises) {return new Promise((resolve, reject) => {for (let i = 0; i < promises.length; i++) {promises[i].then(value => {resolve(value)},reason => {reject(reason)})}})
}

防抖与节流 (重要)

function debounce(fn,wait){let timer = nullreturn function(){let args = argumentslet context = thisif (timer){clearTimeout(timer)timer = null}timer = setTimeout(()=>{fn.apply(context,args)},wait) }
}
// 优化
function debounce(fn, wait, immediate) {let timer = null;return function () {let args = arguments;let context = this;if (timer) {clearTimeout(timer);timer = null;}if (immediate) {let callNow = !timer;timer = setTimeout(() => {timer = null;}, wait);if (callNow) {fn.apply(context, args);}} else {timer = setTimeout(() => {fn.apply(context, args);}, wait);}};
}function throttle(fn,threshold){let timer = nullreturn function(){let args = argumentslet context = thisif (!timer){timer = setTimeout(() => {fn.apply(context,args)timer = null},threshold)}}
}

函数柯里化

function add(){let args = Array.prototype.slice.call(arguments)var adder = function(){args.push(...arguments)return adder}adder.toString = function(){return args.reduce((pre,curr)=>{return pre+curr})}return adder
}
let res = add(1)(2,3)(4)+""
console.log(res);

单例模式

var singletom = (function(){let instance = nullfunction createInstance(name){// 在这里写一些初始化的属性和方法var obj = {};obj.name = namereturn obj}return {getInstance(name){if (!instance){instance = createInstance(name)}return instance}}
})()
var a = singletom.getInstance('a')
var b = singletom.getInstance('b')
console.log(a);
console.log(b);
console.log(a===b);

观察者模式

class Subject{constructor(){this.observers = []}addObserver(observer){this.observers.push(observer)}removeObserver(observer){this.observers = this.observers.filter(ob => ob != observer)}notify(){this.observers.forEach(ob => {ob.callback()})}
}
class Observer {constructor(id,callback){this.id = idthis.callback = callback}
}let ob1 = new Observer(1,()=>{console.log("1已经收到消息");
})
let ob2 = new Observer(2,()=>{console.log("2已经收到消息");
})
let ob3 = new Observer(3,()=>{console.log("3已经收到消息");
})
let subject = new Subject()
subject.addObserver(ob1)
subject.addObserver(ob2)
subject.addObserver(ob3)
subject.removeObserver(ob2)
subject.notify()

消息订阅与发布 (重要)

class Pubsub{constructor(){this.event = {}}pubscribe(topic,callback){if (!this.event[topic]){this.event[topic] = []}this.event[topic].push(callback)}cancel(topic,callback){if (!this.event[topic]){return;}this.event[topic] = this.event[topic].filter(call => call != callback)}publish(topic,content){this.event[topic].forEach(call => {call(content)});}
}
let pubsub = new Pubsub()
function use(content){console.log(content);
}
pubsub.pubscribe('chatGPT',use)
pubsub.pubscribe('cxk',content=>{console.log(content);
})
pubsub.cancel('chatGPT', use)
pubsub.publish('chatGPT',"知道了如何使用chatGPT")
pubsub.publish('cxk',"cxk打篮球")

数组拍平

const arr = ["1", ["2", "3"], ["4", ["5", ["6"]], "7"]]
// 默认只拍平一层
// console.log(arr.flat());
// [ '1', '2', '3', '4', [ '5', [ '6' ] ], '7' ]
// 按传递的参数拍平
// console.log(arr.flat(2));
// [ '1', '2', '3', '4', '5', [ '6' ], '7' ]
console.log(arr.flat(Infinity));
// [ '1', '2', '3', '4', '5', '6', '7' ]let res1 = arr.toString().split(',').map(num => Number(num))
// console.log(res1);let res2 = arr.join().split(',').map(num => Number(num))
// console.log(res2);let res3 = (arr + '').split(',').map(num => Number(num))
console.log(res3);

数组方法

// forEach
Array.prototype.myForEach = function(fn){if (typeof fn != 'function'){throw new TypeError('not a function!')}// 这里的self其实就是数组var self = this // afor(let i = 0; i < self.length; i++){// 回调函数可以传三个参数,分别是当前元素,当前元素下标,整个数组fn(self[i],i,self)}
}
var a = [1,2,3,4]
a.myForEach(num=>{console.log(num);})// map
Array.prototype.myMap = function(fn){if (typeof fn != 'function'){throw new TypeError('not a function')}let self = thislet res = []for(let i = 0; i < self.length; i++){res[i] = fn(self[i],i,self)}return res
}
var a = [1,2,3,4]
var ans = a.myMap(num => num*2)
console.log(ans);// filter
Array.prototype.myFilter = function(fn){if (typeof fn != 'function'){throw new TypeError('not a function')}let self = thislet res = []for(let i = 0; i < self.length; i++){fn(self[i],i,self) && res.push(self[i])}return res
}
var a = [1,2,3,4]
var ans = a.myFilter(num => num > 3)
console.log(ans);// find
Array.prototype.myFind = function(fn){if (typeof fn != 'function'){throw new TypeError('not a function')}let self = thisfor(let i = 0; i < self.length; i++){if (fn(self[i],i,self)){return self[i]}}
}
var a = [1,2,3,4]
var ans = a.myFind(num => num >= 3)
console.log(ans);// every
Array.prototype.myEvery = function(fn){if (typeof fn != 'function'){throw new TypeError('not a function')}let self = thisfor(let i = 0; i < self.length; i++){if (!fn(self[i],i,self)){return false}}return true
}
var a = [1,2,3,4]
var ans = a.myEvery(num => num >= 3)
console.log(ans);// some
Array.prototype.mySome = function(fn){if (typeof fn != 'function'){throw new TypeError('not a function')}let self = thisfor(let i = 0; i < self.length; i++){if (fn(self[i],i,self)){return true}}return false
}
var a = [1,2,3,4]
var ans = a.mySome(num => num >= 3)
console.log(ans);

手写xhr发送请求

待补充

本文链接:https://my.lmcjl.com/post/12141.html

展开阅读全文

4 评论

留下您的评论.