秋招已经逐渐开始,结合各位大佬的手写题对常见题目的做了整理,做复习回顾用。
事件代理
ul.addEventListener('click',function(e){
console.log(e,e.target)
if(e.target&&e.target.tagName.toLowerCase()=='li'){
console.log('打印')
}
})
防抖节流
// 节流,一个单位之间内只触发一次,多次触发只生效一次,重在加锁[flag=false]
function throttle(fn,delay){
let flag = true;
let timer = null;
return function(...args){
let context = this
if(!flag) return
flag = false
clearTimeout(timer)
timer = setTimeout(function(){
fn.apply(context,args)
flag = true
},delay)
}
}
// 防抖,事件被连续触发就重新计时,计时器清零[clearTimeout(timer)]
function debounce(fn, delay){
let timer = null;
return function(...args){
let context = this
if(timer) clearTimeout(timer)
timer = setTimeout(function(){
fn.apply(context,args)
},delay)
}
}
数组去重
// 1.set方法
let arr1 = array=>[...new Set(array)]
// 2.filter
function arr2(array){
var res = array.filter(function(item,index,array){
return array.indexOf(item)===index;
})
return res
}
// 3.object键值对
function arr3(array){
var obj = {}
return array.filter(function(item,index,array){
return obj.hasOwnProperty(typeof item + item)?false:(obj[typeof item+item]=true)
})
}
函数柯里化
function sum(...args1){
return function(...args2){
return [...args1,...args2].reduce((p,n)=>p+n)
}
}
数组flat
let flatDeep = (arr) =>{
return arr.reduce((res,cur)=>{
if(Array.isArray(cur)){
return [...res,...flatDeep(cur)]
}else{
return [...res,cur]
}
},[])
}
function flatten(arr) {
let result=[]
for (let i=0,len=arr.length;i<len;i++) {
if (Array.isArray(arr[i])) {
result=result.concat(flatten(arr[i]))
} else {
result.push(arr[i])
}
}
return result
}
拷贝
// 浅拷贝
obj1 = {...obj}
Object.assign({},obj)
function copy(obj){
let copyobj = {}
for(let key in obj){
copyobj[key] = obj[key]
}
return copyobj
}
// 深拷贝
function deepcopy(obj,map = new WeakMap()){
if(obj instanceof RegExp) return new RegExp(obj);
if(obj instanceof Date) return new Date(obj);
if(typeof obj ==='object'){
let copyobj = Array.isArray(obj)?[]:{};
if(map.get(obj)){
return map.get(obj)
}
map.set(obj,copyobj)
for(let key in obj){
copyobj[key] = deepcopy(obj[key],map);
}
return copyobj
}else{
return obj
}
}
手写call、apply和bind
// call
Function.prototype.maCall = function(){
let [context,...args] = [...arguments]
context = Object(context)||window
let fn = Symbol();
context[fn] = this
let res = context[fn](...args)
delete context[fn]
return res
}
// 手写apply
Function.prototype.myApply = function(){
let [context,args] = [...arguments]
context = Object(context)||window
let fn = Symbol()
context[fn] = this
let res = context[fn](...args)
delete context[fn]
return res
}
// 手写bind
Function.prototype.bind = function(context,...args){
return (...newArgs) =>{
return this.call(context,...args,...newArgs)
}
}
实现new操作
function _new(){
let obj = {};
let [constructor,...args] = [...arguments]
obj._proto_ = constructor.prototype
let res = constructor.apply(obj,args)
return res instanceof Object?res:obj;
}
实现instanceof
function myInstaceof(son,father){
while(true){
son = son._proto_;
if(!son) return false;
if(son = father.prototype) return true
}
}
去除空格
function myTrim(str){
return str.replace(/(^\s+)|(^\s+$)/g,'')
}
手写reduce
Array.prototype.myReduce = function(fn, initVal){
let result = initVal;
let i = 0;
if(typeof initVal == 'undefined'){
result = this[i]
i++;
}
while(i<this.length){
result = fn(result,this[i])
}
return result
}
继承
原型链继承
function Father(){
this.color = []
}
Father.prototype.getColor = function(){
console.log(this.color)
}
function Son(){
this.name =this.name
}
Son.prototype = new Father()
构造函数
function Father(){
}
function Son(){
Father.call(this)
}
var res = new Son()
组合继承
function Father(name){
this.name = name;
this.color = [];
}
Father.prototype.getName = function(){
console.log()
}
function Son(){
Father.call(this)
}
Son.prototype = new Father();
Son.prototyp.constructor = Son
原型式继承
function object(obj){
function F(){}
F.prototype = obj;
return new F()
}
Object.create()
寄生继承
function createAnother(original){
var clone = Object.create(original);
clone.sayHi = function(){
alert('hi')
}
return clone
}
寄生组合继承
Class继承
Class Father{
constructor(name){
this.name = name
}
getName(){
return this.name
}
}
Class Son extends Father{
constructor(name.age){
super(name)
this.age = age
}
}
AJAX
const getJSON = function(url){
return new Promise((resolve,reject)=>{
const xhr = new XMLHttpRequest;
xhr.open('get',url,true)
xhr.setRequestHeader('Accept','application/json')
xhr.onreadystatechange = function(){
if(xhr.readyState!==4) return
if(xhr.status === 200||xhr.status ===304){
resolve(xhr.responseText)
}else{
reject(new Error(xhr.responseText))
}
}
xhr.send()
})
}
手写Promise
const PENDING = 'PENDING';
const FULFILLED = 'FULFILLED';
const REJECTED = 'REJECTED';
class Promise {
constructor(executor) {
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
// 存放成功的回调
this.onResolvedCallbacks = [];
// 存放失败的回调
this.onRejectedCallbacks= [];
let resolve = (value) => {
if(this.status === PENDING) {
this.status = FULFILLED;
this.value = value;
// 依次将对应的函数执行
this.onResolvedCallbacks.forEach(fn=>fn());
}
}
let reject = (reason) => {
if(this.status === PENDING) {
this.status = REJECTED;
this.reason = reason;
// 依次将对应的函数执行
this.onRejectedCallbacks.forEach(fn=>fn());
}
}
try {
executor(resolve,reject)
} catch (error) {
reject(error)
}
}
then(onFulfilled, onRejected) {
if (this.status === FULFILLED) {
onFulfilled(this.value)
}
if (this.status === REJECTED) {
onRejected(this.reason)
}
if (this.status === PENDING) {
// 如果promise的状态是 pending,需要将 onFulfilled 和 onRejected 函数存放起来,等待状态确定后,再依次将对应的函数执行
this.onResolvedCallbacks.push(() => {
onFulfilled(this.value)
});
// 如果promise的状态是 pending,需要将 onFulfilled 和 onRejected 函数存放起来,等待状态确定后,再依次将对应的函数执行
this.onRejectedCallbacks.push(()=> {
onRejected(this.reason);
})
}
}
}
Promise.all
Promise.myAll = function(promiseArr){
return new Promise((resolve,reject)=>{
const ans = [];
let index = 0;
for(let i = 0;i<promiseArr.length;i++){
promiseArr[i].then(res=>{
ans[i] = res;
index++;
if(index==promiseArr.length){
resolve(ans);
}
})
.catch(err=>reject(err))
}
})
}
Promise.race
Promise.race = function(promiseArr){
return new Promise((resolve,reject)=>{
promiseArr.forEach(p=>{
promiseArr.resolve(p).then(
val=>resolve(val),
err=>{reject(err)
})
})
})
}
发布订阅模式
class EventEmitter{
constructor(){
this.events = {}
}
on(eventName,callback){
if(!this.events[eventName]){
this.events[eventName] = [callback]
}else{
this.events[eventName].push(callback)
}
}
emit(eventName,...rest){
if(this.events[eventName]){
this.events[eventName].forEach( item =>{
item.apply(this,rest)
})
}else{
console.log('error')
}
}
remove(eventName,callback){
if(this.events[eventName]){
this.events[eventName] = this.events[eventName].filter( item => item !== callback)
}
}
once(eventName,callback){
function one(){
callback.apply(this,arguments);
this.remove(eventName,one)
}
this.one(eventName,callback)
}
}