javascript高频面试题-- 手写篇(上)

101 阅读4分钟
  1. object() 方法实现?
function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}
  1. Object.create()方法实现?
Object.prototype._create = function(obj, config) {
    function F() {};
    F.prototype = obj;
    const newObj = new F();
    if (config !== null) {
        Object.defineProperties(newObj, config);
    }
    return newObj;
}
  1. Instanceof 方法实现?
function myInstanceof(left, right) {
    let leftPrototype = Object.getPrototypeOf(left);
    while(leftPrototype !== null) {
        if (leftPrototype === right.prototype) {
            return true;
        }
        leftPrototype = Object.getPrototypeOf(leftPrototype);
    }
    return false;
}
  1. Object.is() 方法实现?
Object.prototype._is = function(x, y) {
    if (x === y) {
        return x !== 0 || 1/x === 1/y
    }
    return x !== x && y !== y
}
  1. New 操作符实现?

方法1;

const _new = (func, ...arguments) => {
    let obj = {};
    obj.__proto__ = func.prototype;
    let newObj = func.apply(obj, arguments);
    return newObj instanceof Object ? newObj : obj;
}

方法2:

const _new2 = (func, ...arguments) => {
    let obj = Object.create(null);
    Object.setPrototypeOf(obj, func.prototype);
    let newObj = func.apply(obj, arguments);
    return newObj instanceof Object ? newObj : obj;
}

方法3:

const _new3 = (func, ...arguments) => {
    let obj = Object.create(func.protoype);
    let newObj = func.apply(obj,args);
    return newObj instanceof Object ? newObj : obj;
}
  1. 防抖函数实现?

普通防抖函数:

function debounce(func, delay) {
    let timer;
    return function (...args) {
        if (timer) {
            clearTimeout(timer);
        }
        timer = setTimeout(() => {
            func.apply(this, args);
        }, delay)
    }
}

立即执行防抖函数:

function debounce(func, delay, immediate = false) } {
    let timer;
    return function (...args) {
        if (timer) {
            clearTimeout(timer);
        }
        if(immediate && !timer) {
            func.apply(this, args);
        }
        timer = setTimeout(() => {
            func.apply(this, args);
        }, delay)
    }
 }
  1. 节流函数实现?

节流函数:

function throttle(func, delay) {
    let previous = 0;
    return function(...args) {
        const now = +new Date();
        if ((now - previous) > wait) {
            previous = now;
            fn.apply(this, args);
        }
    }
}
  1. 输入一个值,返回数据的类型?
function type(target) {
    return Object.prototype.toString.call(target);
}
  1. 数组去重的方法?

方法1:

function unique(arr) {
    return [...new Set(arr)];
} 

方法2:

function unique(arr) {
    return arr.filter((item, index) => arr.indexOf(item) === index);
}

方法3:

function unique(arr) {
    return arr.reduce((acc, curr) => {
        if (!acc.includes(curr)) {
            acc.push(curr);
        }
        return acc;
    }, [])
}

方法4:

function unique(arr) {
    const obj = {};
    const newArr = [];
    for(let i = 0; i < arr.length; i++) {
        const item = arr[i];
        if (!obj[item]) {
            newArr.push(item);
            obj[item] = true;
        }
    }
    return newArr;
}

方法 5:

function unique(arr) {
    const map = new Map();
    const newArr = [];
    arr.forEach(item => {
        if(!map.has(item)) {
            map.set(item, true);
            newArr.push(item);
        }
    })
    return newArray;
}
  1. 字符串去重?
function uniqueStr(str) {
    let obj = {};
    let newStr = '';
    for (let i = 0; i< str.length; i++) {
        if (!obj[str[i]]) {
            obj[str[i]] = true;
            newStr += str[i];
        }
    }
    return newStr;
}
  1. Object.assign 实现?
Object.prototype._assign = function(target, argument) {
    const arr = [...argument];
    for(let i = 0; i < arr.length; i++){
        if(arr[i] !== null && arr[i] !== undefined) {
            for (let key in arr[i]) {
                if (arr[i].hasOwnProperty(key)) {
                    target[key] = arr[i][key];
                }
            }
        }
    }
}
  1. 浅拷贝
// 对于对象
Object.assign({}, target);
// 对于数组
[...target];
  1. 深拷贝?
function cloneDeep(obj, hash = new WeakMap()) {
    if (obj === null || typeof obj !== 'object') {
        return obj;    
    }
    if (hash.has(obj)) {
        return hash.get(obj);
    }
    if (obj instanceof Date) {
        return new Date(obj);
    }
    if (obj instanceof RegExp) {
        return new RegExp(obj);
    }
    let result;
    if (Array.isArray(obj)) {
        result = [];
        hash.set(obj, result);
        result = obj.map(item => cloneDeep(item, hash));
    }
    else {
        result = {};
        hash.set(obj, result);
        for (let key in obj) {
            if (obj.hasOwnProperty(key)) {
                result[key] = cloneDeep(obj[key], hash);
            }
        }
    }
    return result;
}
  1. Reverse的实现?
Array.prototype._reverse = funciton() {
    let left = 0;
    let right = this.length - 1;
    while (left < right) {
        [this[left], this[right]] = [this[right], this[left]];
        left++;
        right--;
    }
    return this;
}    
  1. 寄生式组合式继承?
function Parent(name) {
    this.name = name;
}
Parent.prototype.say = function() {
    console.log(this.name);
}

function Child(name, age){
    Parent.call(this, name);
    this.age = age;
}
function inheritPrototype(parent,child) {
     let prototype = Object.create(parent.prototype); // 创建对象 
     prototype.constructor = child; // 增强对象 解决重写原型constructor丢失问题
     child.prototype = prototype; // 赋值对象 将新创建的对象赋值给子类型的原型
}
inheritPrototype(Parent, Child);
let instance = new Child('test', 19);
  1. 找出字符串中第一次只出现一次的字母 ?
String.prototype.firstApper = function() {
    const obj = {};
    const len = this.length;
    for (let i = 0; i < len; i++) {
        if (obj[this[i]]) {
            obj[this[i]] += 1
        }
        else {
            obj[this[i]] = 1
        }
    }
    for (let key in Obj) {
        if (obj[key] === 1) {
            return key;
        }
    }
    return null;
}
  1. Reduce 的实现?
Array.prototype._reduce = function(func, initValue) {
    const arr = this;
    let accu;
    let index;
    if (initVlue !== undefined) {
        accu = initValue;
        index = 0;
    }
    else {
        if (arr.length === 0) {
            throw new TypeError('no data for array and no initValue');
            accu = arr[0];
            index = 1;
        }
    }
    for (let i = index; i < arr.lengthl; i++) {
        accu = func(accu, arr[i], i, arr);
    }
    return accu;
}
  1. 检查字符串是否是回文字符串?
function isPalindrome(str) {
    if (typeof str !== 'string') {
        return false;
    }
    let left = 0;
    let right = str.length - 1;
    while(left < right) {
        let s1 = str[left].toLowerCase();
        let s2 = str[right].toLowerCase();
        if (s1 !== s2) {
            return false;
        }
        i++;
        j--;
    }
    return true
}
  1. forEach的实现?
Array.prototype._forEach = function (func, thisArg) {
    if (typeof func !== 'function') {
        throw new TypeError(func + ' is not function')
    }
    const len = this.length;
    for (let i = 0; i < len; i++) {
        func.call(thisArg | this, this[i], i, this);
    }
} 
  1. filter 函数的实现?
Array.prototype._filter = funciton(callback, thisArg) {
    let new = [];
    for(let i = 0; i< this.length; i++) {
        callback.call(thisArg || this, this[i], i, this) && new.push(this[i]);
    }
    return new;
}
  1. Map 函数的实现?
Array.prototype._map = function(callback) {
    const newArr = [];
    const len = this.length;
    const _this = argument[1] || window;
    for (let i = 0; i < len; i++) {
       newArr.push(callback.call(_this, this[i], i, this));
    }
    return newArr;
}
  1. 获取url中的参数 ?
function requestParamsToJson(url = window.location.href) {
    const searchStr = url.split('?')[1];
    const obj = {};
    if (serachStr) {
        let arr = serachStr.split('&');
        for(let i = 0; i< arr.length; i++) {
            const part = arr[i].split('=');
            const key = decodeURIComponent(part[0]);
            const value = decodeURIComponent(part[1]);
            obj[key] = value;
        }
    }
    return obj;
}
  1. 数组排序?

冒泡:

function bubbleSort(arr) {
    let len = array.length;
    for (let i = 0; i < len - 1; i++) {
        let swapped = false;
        for (let j = 0; j < len - 1 - i; j++) {
            if (arr[j] > arr[j + 1]) {
                [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
                swapped = true;
            }
        }
        if (!swapped) {
            break;
        }
    }
    return arr;
} 

快速排序:

function quickSort(arr) {
    if (arr.length <= 1) {
        return arr;
    }
    let left = [], right = [];
    let pIndex = Math.floor(arr.length / 2);
    let p = arr.splice(pIndex, 1)[0];
    for (let i = 0; i < arr.length; i++) {
        if (arr[i] <= p) {
            left.push(arr[i]);
        }
        else {
            right.push(right);
        }
    }
    return quickSort(left).concat([p], quickSort(right));
  }
  1. 实现apply()方法?
Fuction.prototype.myApply = function(context, args) {
    context = context || window;
    context.fn = this;
    let result;
    if (!args) {
        result = context.fn();
    }
    else {
        result = context.fn(args);
    }
    delete context.fn;
    return result;
}
  1. 实现call() 方法?
Function.protptype.myCall = function(context, ...args) {
    context = context || window;
    context.fn = this;
    let result = context.fn(...args);
    delete context.fn;
    return result;
}
  1. 实现bind()方法?
Function.protoytpe.myBind = function(context, ...bindArgs) {
    if (typeof this !== 'function') {
        throw new TypeError('bind must be called on a function')
    }
    let seft = this;
    function bindFunction(...args) {
        let isNew = this instanceof bindFunction;
        let contextThis = isNew ? this : context;
        self.apply(contextThis, [...bindArgs, ...args]);
    }
    if (this.prototype) {
        bindFunction.prototype = Object.create(this.prototype);
    }
    return bindFunction;
}
  1. 函数柯里化?
function curry(fn) {
    let len = fn.length;
    function curried(...args) {
        if (args.length >= len) {
            fn(...args);
        }
        else {
            return function(...moreArgs) {
                curried(...args, ...moreArgs);
            }
        }
    }
}
  1. 数组扁平化?

基本方法:

function falt(arr, depth = 1) {
    let res = [];
    for (let i = 0; i < arr.length; i++) {
        if (Array.isArray(arr[i]) && depth !== 0) {
            // infinity - 1  结果还是 infinity
            res = res.concat(flat(arr[i]), depth - 1)
        } else {
            res.push(arr[i])
        }
    }
    return res
}
  1. promise.allSettled 实现?
function promiseAllSettled(promises) {
    return new Promise((resolve, reject) => {
        if (!Array.isArray(promises)) {
            return reject(new TypeError("参数必须是一个数组"));
        }
        const result = [];
        let count = 0;
        promises.forEach((item, index) => {
            Promise.resolve(item).then(
                (value) => {
                    result[index] = {
                        status: "fulfilled",
                        value
                    };
                    count++;
                    if (count === promises.length) {
                        resolve(result);
                    }
                },
                (error) => {
                    result[index] = {
                        status: "rejected",
                        error
                    };
                    count++;
                    if (count === promises.length) {
                        resolve(result);
                    }
                }
            )
        })
    })
}