JS手写题

题目(大部分转自第一个参考网站)

AJAX

var request = new XMLHttpRequest()
 request.open('GET', 'index/a/b/c?name=TianTian', true);
 request.onreadystatechange = function () {
   if(request.readyState === 4 && request.status === 200) {
     console.log(request.responseText);
   }};
 request.send();

事件委托

function delegate(element, eventType, selector, fn) {
    element.addEventListener(eventType, e => {
        let el = e.target
        while (!el.matches(selector)) {
            if (element === el) {
                el = null
                break
            }
            el = el.parentNode
        }
        el && fn.call(el, e, el)
    },true)
    return element
}

防抖

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)
    }
}

节流

function throttle(fn, delay) {
    let flag = true,
        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)
    }
}

数组去重

使用Set
let unique_1 = arr => [...new Set(arr)];
使用filter
function unique_2(array) {
    var res = array.filter(function (item, index, array) {
        return array.indexOf(item) === index;
    })
    return res;
}
reduce
let unique_3 = arr => arr.reduce((pre, cur) => pre.includes(cur) ? pre : [...pre, cur], []);
Object 键值对
function unique_4(array) {
    var obj = {};
    return array.filter(function (item, index, array) {
        return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
    })
}

数组扁平化

ES6 自带Array.prototype.flat(num)

function flatDeep(arr, d = 1) {
    return d > 0 ? arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? flatDeep(val, d - 1) : val),
    []) :
        arr.slice();
};

// var arr1 = [1,2,3,[1,2,3,4, [2,3,4]]];
// flatDeep(arr1, Infinity);

call和apply


// 实现call
Function.prototype.mycall = function () {
    let [thisArg, ...args] = [...arguments]
    thisArg = Object(thisArg) || window
    let fn = Symbol()
    thisArg[fn] = this
    let result = thisArg[fn](...args)
    delete thisArg[fn]
    return result
}
// 实现apply
Function.prototype.myapply = function () {
    let [thisArg, args] = [...arguments];
    thisArg = Object(thisArg)
    let fn = Symbol()
    thisArg[fn] = this;
    let result = thisArg[fn](...args);
    delete thisArg.fn;
    return result;
}

//测试用例
let cc = {
    a: 1
}

function demo(x1, x2) {
    console.log(typeof this, this.a, this)
    console.log(x1, x2)
}
demo.apply(cc, [2, 3])
demo.myapply(cc, [2, 3])
demo.call(cc,33,44)
demo.mycall(cc,33,44)

bind


// 实现bind
Function.prototype.mybind = function(context, ...args){
    return (...newArgs) => {
        return this.call(context,...args, ...newArgs)
    }
}

// 测试用例
let cc = {
    name : 'TianTian'
}
function say(something,other){
    console.log(`I want to tell ${this.name} ${something}`);
    console.log('This is some'+other)
}
let tmp = say.mybind(cc,'happy','you are kute')
let tmp1 = say.bind(cc,'happy','you are kute')
tmp()
tmp1()

深拷贝

function deepClone(obj, map = new WeakMap()) {
    if (obj instanceof RegExp) return new RegExp(obj);
    if (obj instanceof Date) return new Date(obj);

    if (obj == null || typeof obj != 'object') return obj;
    if (map.has(obj)) {
        return map.get(obj);
    }
    let t = new obj.constructor();
    map.set(obj, t);
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            t[key] = deepClone(obj[key], map);
        }
    }
    return t;
}
//测试用例
let obj = {
    a: 1,
    b: {
        c: 2,
        d: 3
    },
    d: new RegExp(/^\s+|\s$/g)
}

let clone_obj = deepClone(obj)
obj.d = /^\s|[0-9]+$/g
console.log(clone_obj)
console.log(obj)

Object.create


//实现Object.create方法
function create(proto) {
    function Fn() {};
    Fn.prototype = proto;
    Fn.prototype.constructor = Fn;
    return new Fn();
}
let demo = {
    c : '123'
}
let cc = Object.create(demo)

手写继承

寄生组合式(常用)
function inheritPrototype(subType, superType) {
    // 创建对象,创建父类原型的一个副本
    var prototype = Object.create(superType.prototype); 
    // 增强对象,弥补因重写原型而失去的默认的constructor 属性
    prototype.constructor = subType; 
    // 指定对象,将新创建的对象赋值给子类的原型
    subType.prototype = prototype; 
}
Class实现
class Rectangle {
    // constructor
    constructor(height, width) {
        this.height = height;
        this.width = width;
    }
    // Getter
    get area() {
        return this.calcArea()
    }
    // Method
    calcArea() {
        return this.height * this.width;
    }
}

const rectangle = new Rectangle(40, 20);
console.log(rectangle.area);
// 输出 800
// 继承
class Square extends Rectangle {
    constructor(len) {
        // 子类没有this,必须先调用super
        super(len, len);

        // 如果子类中存在构造函数,则需要在使用“this”之前首先调用 super()。
        this.name = 'SquareIng';
    }
    get area() {
        return this.height * this.width;
    }
}
const square = new Square(20);
console.log(square.area);
// 输出 400

Promise源码

const PENDING = 'PENDING';      // 进行中
const FULFILLED = 'FULFILLED';  // 已成功
const REJECTED = 'REJECTED';    // 已失败
class Promise {
    constructor(exector) {    // 初始化状态    
        this.status = PENDING;
        // 将成功、失败结果放在this上,便于then、catch访问
        this.value = undefined; this.reason = undefined;    // 成功态回调函数队列   
        this.onFulfilledCallbacks = [];    // 失败态回调函数队列    
        this.onRejectedCallbacks = [];
        const resolve = value => {      // 只有进行中状态才能更改状态      
            if (this.status === PENDING) {
                this.status = FULFILLED;
                this.value = value;        // 成功态函数依次执行        
                this.onFulfilledCallbacks.forEach(fn => fn(this.value));
            }
        }
        const reject = reason => {      // 只有进行中状态才能更改状态      
            if (this.status === PENDING) {
                this.status = REJECTED;
                this.reason = reason;        // 失败态函数依次执行        
                this.onRejectedCallbacks.forEach(fn => fn(this.reason))
            }
        }
        try {
            // 立即执行executor      
            // 把内部的resolve和reject传入executor,用户可调用resolve和reject     
            exector(resolve, reject);
        } catch (e) {
            // executor执行出错,将错误内容reject抛出去      
            reject(e);
        }
    } then(onFulfilled, onRejected) {
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
        onRejected = typeof onRejected === 'function' ? onRejected :
            reason => { throw new Error(reason instanceof Error ? reason.message : reason) }    // 保存this    
        const self = this; return new Promise((resolve, reject) => {
            if (self.status === PENDING) {
                self.onFulfilledCallbacks.push(() => {
                    // try捕获错误          
                    try {
                        // 模拟微任务            
                        setTimeout(() => {
                            const result = onFulfilled(self.value);
                            // 分两种情况:             
                            // 1. 回调函数返回值是Promise,执行then操作
                            // 2. 如果不是Promise,调用新Promise的resolve函数
                            result instanceof Promise ? result.then(resolve, reject) : resolve(result);
                        })
                    } catch (e) { reject(e); }
                }); 
                self.onRejectedCallbacks.push(() => {
                    // 以下同理          
                    try {
                        setTimeout(() => {
                            const result = onRejected(self.reason);
                            // 不同点:此时是reject             
                            result instanceof Promise ? result.then(resolve, reject) : reject(result);
                        })
                    } catch (e) { reject(e); }
                })
            } else if (self.status === FULFILLED) {
                try {
                    setTimeout(() => {
                        const result = onFulfilled(self.value); result instanceof Promise ? result.then(resolve, reject) : resolve(result);
                    });
                } catch (e) { reject(e); }
            } else if (self.status === REJECTED) {
                try {
                    setTimeout(() => {
                        const result = onRejected(self.reason); result instanceof Promise ? result.then(resolve, reject) : reject(result);
                    })
                } catch (e) { reject(e); }
            }
        });
    } catch(onRejected) {
        return this.then(null, onRejected);
    } static resolve(value) {
        if (value instanceof Promise) {
            // 如果是Promise实例,直接返回     
            return value;
        } else {
            // 如果不是Promise实例,返回一个新的Promise对象,状态为FULFILLED     
            return new Promise((resolve, reject) => resolve(value));
        }
    } static reject(reason) {
        return new Promise((resolve, reject) => {
            reject(reason);
        })
    }
}

Promise.all 及 race

// 实现Promise.all 以及 race

Promise.myall = function (arr) {
    return new Promise((resolve, reject) => {
        if (arr.length === 0) {
            return resolve([])
        } else {
            let res = [],
                count = 0
            for (let i = 0; i < arr.length; i++) {
                // 同时也能处理arr数组中非Promise对象
                if (!(arr[i] instanceof Promise)) {
                    res[i] = arr[i]
                    if (++count === arr.length)
                        resolve(res)
                } else {
                    arr[i].then(data => {
                        res[i] = data
                        if (++count === arr.length)
                            resolve(res)
                    }, err => {
                        reject(err)
                    })
                }

            }
        }
    })
}

Promise.myrace = function (arr) {
    return new Promise((resolve, reject) => {
        for (let i = 0; i < arr.length; i++) {
            // 同时也能处理arr数组中非Promise对象
            if (!(arr[i] instanceof Promise)) {
                Promise.resolve(arr[i]).then(resolve, reject)
            } else {
                arr[i].then(resolve, reject)
            }

        }
    })
}

参考网站

送你21道精选高频JavaScript手写面试题
32个手写JS,巩固你的JS基础
12道高频 JavaScript 手写面试题及答案

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值