前端面试题汇总(待续)

【】插入排序

var arr = [1, 3, 2, 7, 4, 5, 6, 8, 7];
var current = null
var preIndex = null
var insertionSort = (arr) => {
    for (var i = 1; i < arr.length; i++){
        preIndex = i - 1;
        current = arr[i]
        while(preIndex >= 0 && current < arr[preIndex]) {
            arr[preIndex + 1] = arr[preIndex]
            preIndex --;
        }
        arr[preIndex + 1] = current
    }
    return arr
}
insertionSort(arr);

【】选择排序

var arr = [1, 3, 2, 7, 4, 5, 6, 8, 7]
var index = null
var selectionSort = (arr) => {
    for (var i = 0; i < arr.length - 1; i++) {
        index = i;
        for (var j = i + 1; j < arr.length; j++) {
            if (arr[j] < arr[index]) {
                index = j
            }
        }
        var temp = arr[i]
        arr[i] = arr[index]
        arr[index] = temp
    }
    return arr;
}
selectionSort(arr)

【】冒泡排序

var arr = [1, 3, 2, 7, 4, 5, 6, 8]
var bubbleSort = (arr) => {
    for (var i = 0; i < arr.length - 1; i++) {
        for (var j = 0; j < arr.length - 1 - i; j++) {
            if (arr[j+1] < arr[j]) {
                var temp = arr[j+1];
                arr[j+1] = arr[j];
                arr[j] = temp;
            }
        }
    }
    return arr;
}
bubbleSort(arr)

【】es5实现const

const _const = (key, value) => {
     const desc = {        
        value,        
        writable: false    
    }    
    Object.defineProperty(window, key, desc)
}
_const('obj', {a: 1});
console.log(obj.a);
obj = {}; // Cannot redefine property: obj

【】es5实现let

(function() {
    for(var i = 0; i < 3; i++) {
        console.log(i);
    }
})();
console.log(i); // Uncaught ReferenceError: i is not defined

【】数组扁平化的几种方式

1.es6的flat
var arr = [1,[2,3],[4,[5,6]],7];
console.log(arr.flat(Infinity));

2.序列化后正则
var arr = [1,[2,3],[4,[5,6]],7];
var str = `[${JSON.stringify(arr).replace(/[|]/g, '')}]`;
console.log(JSON.parse(str));

3.reduce递归
var arr = [1,[2,3],[4,[5,6]],7];
var flat = (arr) => {
  return arr.reduce((prev, cur) => {
    return prev.concat(cur instanceof Array ? flat(cur) : cur)
  }, [])
}
flat(arr);

4.递归
var arr = [1,[2,3],[4,[5,6]],7];
var flat = (arr) => {
  let result = []
  for (var item of arr) {
    item instanceof Array ? result = result.concat(flat(item)) : result.push(item)
  }
  return result
};
flat(arr);

5.迭代+展开运算符
var arr = [1,[2,3],[4,[5,6]],7];
while(arr.some(Array.isArray)){
    arr = [].concat(...arr);
}
console.log(arr)

【】函数柯里化

概念:柯里化是一个函数转换的过程,是指把接收多个参数的函数变换成接收单一参数的函数,嵌套返回直到所有参数都被使用并返回最终结果。将fn(a,b,c)转为fn(a)(b)(c),它不会调用函数。

function addThreeNum (a, b, c) {
    return a + b + c;
}
addTreeNum(6, 9 ,10);// 返回结果为25
------------------

function addhTreeNumCurry(a) {
    return function(b) {
        return function(c) {
            return a + b + c;
        }
    }
}
addThreeNumCurry(6)(9)(10);// 返回结果同样是25

// 分部调用柯里化后的函数
const add1 = addThreeNumCurry(6);// 返回的是一个函数
const add2 = add1(9);// 返回的是一个函数
const add3 = add2(10);// 已接收到所有的参数,返回最终的计算结果

console.log(add3);// 25

【】ES6的extends继承

class A {
    constructor() {
        this.name = 'A';
    }
    getName() {
        return this.name;
    }
}

class B extends A {
    constructor() {
        super();

        this.name = 'B';
    }
}

let bIn = new B();
console.log(bIn.getName())

【】原型链继承

function A(aName) {
    this.aName = aName;
    this.sayA = function() {
        console.log(this.aName);
    };
    
}
A.prototype.age = 10;
function B() {}
B.prototype = new A('bName');
var test = new B();
console.log(test.sayA())


【】原型式继承

function A(aName) {
    this.aName = aName;
    this.sayA = function() {
        console.log(this.aName);
    };
    
}
A.prototype.age = 10;
function sup(obj) {
    function F() {} 
    F.prototype = obj;
    return new F();
}
var test1 = new A('test');
var test2 = sup(test1);
console.log(test1.sayA())
console.log(test2.sayA())


【】构造函数继承

function A(aName) {
    this.aName = aName;
    this.sayA = function() {
        console.log(this.aName);
    };
    
}
A.prototype.age = 10;
function B() {
    A.call(this, 'bName')
}
var test = new B();
console.log(test.sayA())


【】组合继承

function A(aName) {
    this.aName = aName;
    this.sayA = function() {
        console.log(this.aName);
    };
    
}
A.prototype.age = 10;
function B(aName) {
    A.call(this, aName)
}
B.prototype = new A();
var test = new B('testName');
console.log(test.sayA())

【】寄生式继承

function A(aName) {
    this.aName = aName;
    this.sayA = function() {
        console.log(this.aName);
    };
    
}
A.prototype.age = 10;

function sup(obj) {
    function F() {}
    F.prototype = obj;
    return new F();
}

function supN(obj) {
    var supN = sup(obj);
    supN.newAge = 20;
    return supN;
}


var aIn = new A('aIn');
var bIn = supN(aIn);
console.log(aIn.age)
console.log(aIn.newAge)
console.log(bIn.newAge)

【】寄生组合式继承

function A(aName) {
    this.aName = aName;
    this.sayA = function() {
        console.log(this.aName);
    };
    
}
A.prototype.age = 10;

function sup(obj) {
    function F() {}
    F.prototype = obj;
    return new F();
}
var temp = sup(A.prototype);

function B(name) {
    A.call(this, name);
}
B.prototype = temp;


var test1 = new B('test1');

console.log(test1.sayA())
console.log(temp)

【】JS解决异步的方法有哪些

1.回调函数
2.事件监听
3.发布-订阅
4.Promise
5.Generator
6.Async/Await
7.yield

【】JS有几种数据类型

1.null
2.undefined
3.boolean
4.number
5.string
6.symbol
7.bigInt
9.array
10.object
11.function

【】获取DOM里所有标签

new Set([...document.querySelectorAll('*')].map(e => e.tagName))

【】对象的深浅拷贝

var obj = {
    a: null,
    b: undefined,
    c: function() {
        console.log('c');
    },
    d: 'd_value',
    e: {
        e1: null,
        e2: undefined,
        e3: function() {
            console.log('e3');
        },
        e4: 'e4_value',
        e5: {
            e51: null,
            e52: undefined,
            e53: function() {
                console.log('e53');
            },
            e54: 'e54'
        }
    }
}



1.JSON.parse(JSON.stringify(obj))
缺点:不可以拷贝一些特殊的属性(例如正则表达式,undefine,function)
var obj_clone = JSON.parse(JSON.stringify(obj));
console.log(obj_clone)

2.递归
var deepClone = (obj) => {
    if (toString.call(obj).search('Object') === -1) {
        return;
    } 
    let obj_clone = toString.call(obj).search('Object') !== -1 ? {} : [];
    for (var key in obj) {
        if (obj[key] && toString.call(obj[key]).search('Object') !== -1) {
            obj_clone[key] = deepClone(obj[key]);
        } else {
            obj_clone[key] = obj[key];
        }
    }
    return obj_clone;
}
var obj_clone = deepClone(obj);
console.log(obj_clone);

3.用Object.assign。
当对象中只有一级属性,没有二级属性的时候,此方法为深拷贝,但是对象中有对象的时候,此方法,在二级属性以后就是浅拷贝。
var obj_clone = Object.assign(obj);
console.log(obj_clone);

【】判断数据类型的几种方式

console.log(typeof 1);               // number
console.log(typeof true);            // boolean
console.log(typeof 'mc');           // string
console.log(typeof function(){});    // function
console.log(typeof []);              // object
console.log(typeof {});              // object
console.log(typeof null);            // object
console.log(typeof undefined);       // undefined
优点:能够快速区分基本数据类型 缺点:不能将Object、Array和Null区分,都返回object。
原理:不同的对象在底层都表示为二进制,在Javascript中二进制前(低)三位存储其类型信息。
000: 对象
010: 浮点数
100:字符串
110: 布尔
1: 整数

console.log(1 instanceof Number);                    // false
console.log(true instanceof Boolean);                // false 
console.log('str' instanceof String);                // false  
console.log([] instanceof Array);                    // true
console.log(function(){} instanceof Function);       // true
console.log({} instanceof Object);                   // true
优点:能够区分Array、Object和Function,适合用于判断自定义的类实例对象 缺点:Number,Boolean,String基本数据类型不能判断
原理: 检测 constructor.prototype是否存在于参数 object的 原型链上。
object instanceof constructor 等同于 constructor.prototype.isPrototypeOf(object)


var toString = Object.prototype.toString;
console.log(toString.call(1));                      //[object Number]
console.log(toString.call(true));                   //[object Boolean]
console.log(toString.call('mc'));                  //[object String]
console.log(toString.call([]));                     //[object Array]
console.log(toString.call({}));                     //[object Object]
console.log(toString.call(function(){}));           //[object Function]
console.log(toString.call(undefined));              //[object Undefined]
console.log(toString.call(null));                   //[object Null]
优点:精准判断数据类型 缺点:写法繁琐不容易记,推荐进行封装后使用
原文地址:https://www.cnblogs.com/cynthia-wuqian/p/12869249.html