前端算法面试题

271 阅读2分钟

原型链继承

 function Animal(){
            this.color=['red','pink'];
        }
        Animal.prototype.getColor=function(){
            return this.color;
        }
        function Dog(){

        }
        Dog.prototype=new Animal();
        let dog1=new Dog();
        dog1.color.push('blue');
        let dog2=new Dog();
        console.log(dog2.color)

构造函数继承

 function Animal(name){
            this.name=name;
            this.getName=function(){
                return this.name;
            }
        }
        function Dog(name){
            Animal.call(this,name); //调用animal方法,传入参数name
        }
        Dog.prototype=new Animal();

寄生式组合继承

function objectCopy(obj) {
  function Fun() { };
  Fun.prototype = obj;
  return new Fun();
}

function inheritPrototype(child, parent) {
  let prototype = objectCopy(parent.prototype); // 创建对象
  prototype.constructor = child; // 增强对象
  Child.prototype = prototype; // 赋值对象
}

function Parent(name) {
  this.name = name;
  this.friends = ["rose", "lily", "tom"]
}

Parent.prototype.sayName = function () {
  console.log(this.name);
}

function Child(name, age) {
  Parent.call(this, name);
  this.age = age;
}

inheritPrototype(Child, Parent);
Child.prototype.sayAge = function () {
  console.log(this.age);
}

let child1 = new Child("yhd", 23);
child1.sayAge(); // 23
child1.sayName(); // yhd
child1.friends.push("jack");
console.log(child1.friends); // ["rose", "lily", "tom", "jack"]

函数防抖

   function debonce(func,wait){
            var timeout;
            return function(){
                var context=this;
                var args=srguments;
                clearTimeout(timeout)
                timeout=setTimeout(function(){
                    func.apply(context,args)
                },wait)
            }
        }
       

函数节流

 function throttle(func,wait){
            var context,args;
            var previous=0;
            return function(){
                var now=new Date();
                context=this;
                args=arguments;
                if(now-previous>wait){
                    func.apply(context.args);
                    orevious=now;
                }
            }
        }

函数的深浅拷贝

 //浅拷贝
        function shallowCopy(obj){
            if(typeof obj!=='object') return;
            let newObj=obj instanceof Array?[]:{};
            for(var k in obj){
                if(obj.hasOwnProperty(k)){
                    newObj[k]=obj[k]
                }
            }
            return newObj
        }

       //深拷贝
       const isObject=(target)=>(typeof target ==='object'||typeof target ==='function')&& target!==null;
function deepClone(target, map = new WeakMap()) {
    if (map.get(target)) {
        return target;
    }
    // 获取当前值的构造函数:获取它的类型
    let constructor = target.constructor;
    // 检测当前对象target是否与正则、日期格式对象匹配
    if (/^(RegExp|Date)$/i.test(constructor.name)) {
        // 创建一个新的特殊对象(正则类/日期类)的实例
        return new constructor(target);  
    }
    if (isObject(target)) {
        map.set(target, true);  // 为循环引用的对象做标记
        const cloneTarget = Array.isArray(target) ? [] : {};
        for (let prop in target) {
            if (target.hasOwnProperty(prop)) {
                cloneTarget[prop] = deepClone(target[prop], map);
            }
        }
        return cloneTarget;
    } else {
        return target;
    }
}

数据类型判断

  function typeOf(obj){
           let res=Object.prototype.toString.call(obj).split(' ')[1];
           res=res.substring(0,res.length-1).toLowerCase();
           return res
       }
       typeOf([]);
       typeOf({});
       typeOf(new Date);

数组扁平化

  var arr1=[1, [2, [3]]];
        function flatten(arr){
            var result=[];
           for(var i=0;i<arr.length;i++){
               if(Array.isArray(arr[i])){
                   result=result.concat(flatten(arr[i]))
               }else{
                   result=result.push(arr[i])
               }
           }
           return result;
        }
      
        //es6 
        function flatten(arr){
            while(arr.some(item=>Array.isArray(item))){
                arr=[].concat(...arr)
            }
            return arr;
        }

数组去重

 var arr=[1,1,2,2,0]
        var result=[];
        for(var i=0;i<arr.length;i++){
            if(!result.includes(arr[i])){
                result.push(arr[i])
            }
           
        }
        console.log(result);

        //es6 写法
        var unique = arr => [...new Set(arr)]

call

Function.prototype.call2 = function (context) {
    var context = context || window;
    context.fn = this;

    var args = [];
    for(var i = 1, len = arguments.length; i < len; i++) {
        args.push('arguments[' + i + ']');
    }

    var result = eval('context.fn(' + args +')');

    delete context.fn
    return result;
}

作者:大海我来了
链接:https://juejin.cn/post/6946022649768181774
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

bind

Function.prototype.bind2 = function (context) {
    var self = this;
    var args = Array.prototype.slice.call(arguments, 1);

    var fNOP = function () {};

    var fBound = function () {
        var bindArgs = Array.prototype.slice.call(arguments);
        return self.apply(this instanceof fNOP ? this : context, args.concat(bindArgs));
    }

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();
    return fBound;
}

作者:大海我来了
链接:https://juejin.cn/post/6946022649768181774
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

apply

Function.prototype.apply2 = function (context, arr) {
    var context = context || window;
    context.fn = this;

    var result;
    if (!arr) {
        result = context.fn();
    } else {
        var args = [];
        for (var i = 0, len = arr.length; i < len; i++) {
            args.push('arr[' + i + ']');
        }
        result = eval('context.fn(' + args + ')')
    }

    delete context.fn
    return result;
}

作者:大海我来了
链接:https://juejin.cn/post/6946022649768181774
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Promise.all

Promise.all 的规则是这样的:

传入的所有 Promsie 都是 fulfilled,则返回由他们的值组成的,状态为 fulfilled 的新 Promise; 只要有一个 Promise 是 rejected,则返回 rejected 状态的新 Promsie,且它的值是第一个 rejected 的 Promise 的值; 只要有一个 Promise 是 pending,则返回一个 pending 状态的新 Promise;

Promise.all = function(promiseArr) {
    let index = 0, result = []
    return new Promise((resolve, reject) => {
        promiseArr.forEach((p, i) => {
            Promise.resolve(p).then(val => {
                index++
                result[i] = val
                if (index === promiseArr.length) {
                    resolve(result)
                }
            }, err => {
                reject(err)
            })
        })
    })
}

作者:大海我来了
链接:https://juejin.cn/post/6946022649768181774
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

快速排序

const quickSort = (arr) =>{
  if(arr.length <= 1){ return arr };
  let pivotIndex = Math.floor(arr.length/2);
  let pivot = arr.splice(pivotIndex,1)[0] ;//确定基准
  let left = , right = [];
  for(let i = 0;i<arr.length;i++){
    if(arr[i]<pivot){
       left.push(arr[i]);
     }else{
       right.push(arr[i]);
}
}
   return quickSort(left).concat([pivot],quickSort(right));
}

数组冒泡

冒泡排序:一次又一次的进行多次项的两两比较,比较次数n(n-1)/2

 for (var i = 1; i < arr.length; i++) {
            // 内层循环负责两两比较
            for (var j = arr.length - 1; j >= i; j--) {
                // 判断项的大小
                if (arr[j] < arr[j - 1]) {
                    // 这一项比前一项还小了,那么就要交换两个变量的位置
                    var temp = arr[j];
                    arr[j] = arr[j - 1];
                    arr[j - 1] = temp;
                }
            }
            console.log(arr);
        }
console.log(arr);

斐波那契数列

 // 编写一个函数,这个函数的功能是返回斐波那契数列中下标为n的那项的值
        function fib(n) {
            // 数列的下标为0的项,和下标为1的项值是1
            if (n == 0 || n == 1) return 1;
            // 斐波那契数列的本质特征就是每一项,都等于前面两项的和
            return fib(n - 1) + fib(n - 2);
        }

        // 书写一个循环语句,计算斐波那契数列的前15项
        for (var i = 0; i < 15; i++) {
            console.log(fib(i));
        }