前端面试题手撕小结

这篇博客总结了前端面试中常见的几个问题,包括如何实现`flat`函数的多种方式,编写随机打乱数组的方法,设计随机红包分配算法,深入理解函数柯里化,以及求解对象的深度。通过这些实例,有助于提升JavaScript编程技巧和面试准备。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.实现flat函数

> const animals = ["🐷", ["🐶", "🐂"], ["🐎", ["🐑", ["🐲"]], "🐛"]];
> 
> // 不传参数时,默认“拉平”一层 
> animals.flat(); 
> // ["🐷", "🐶", "🐂", "🐎", ["🐑",["🐲"]], "🐛"]
> 
> // 传入一个整数参数,整数即“拉平”的层数 
> animals.flat(2); 
> // ["🐷", "🐶", "🐂", "🐎", "🐑", ["🐲"], "🐛"]
> 
> // Infinity 关键字作为参数时,无论多少层嵌套,都会转为一维数组 
> animals.flat(Infinity);
>  //["🐷", "🐶", "🐂", "🐎", "🐑", "🐲", "🐛"]
> 
> // 传入 <=0 的整数将返回原数组,不“拉平”
>  animals.flat(0); 
>  animals.flat(-10); 
>  //["🐷", ["🐶", "🐂"], ["🐎", ["🐑", ["🐲"]], "🐛"]];
> 
> // 如果原数组有空位,flat()方法会跳过空位。
>  ["🐷", "🐶", "🐂", "🐎",,].
>  flat();
>   // ["🐷", "🐶", "🐂", "🐎"]
  • 简单实现
let a=[1,2,[3,[4,5],6],7,[{tt:2},[1,2]]]
let newA=[];
function flat(a){
    for(let i=0;i<a.length;i++){
        if(Array.isArray(a[i])){
            flat(a[i]);
        }else{
            newA.push(a[i]);
        }
    }
} 
flat(a)
newA
  • 第二问:用 reduce 实现 flat 函数
let a=[1,2,[3,[4,5],6],7,[{tt:2},[1,2]]]
const flat=(arr)=>arr.reduce((pre,cur)=>{
    return pre.concat(Array.isArray(cur)?flat(cur):cur)
},[])
let newA=flat(a);
newA
  • 第三问:实现在原型链上重写 flat 函数
Array.prototype.fakeFlat = function(num = 1) {
  if (!Number(num) || Number(num) < 0) {
    return this;
  }
  let arr = [...this];    
  while (num ) {
     if(arr.some(item=>Array.isArray(item))) {
        arr = [].concat(... arr);
		num--;
      }else{
      	break;
      }
  }
  return arr;
};

引用:面试官连环追问:数组拍平(扁平化) flat 方法实现

2.写一个方法将一个数组随机打乱

let a=[1,2,3,4,5,6,7,8];
a.sort(()=>Math.random()-0.5)
a
let a=[1,2,3,4,5,6,7,8];
for(let i=0;i<a.length;i++){
    let temp=parseInt(Math.random()*(a.length-1));
    [a[i],a[temp]]=[a[temp],a[i]]
}

引用: 写一个方法将一个数组随机打乱

3.实现一个分配随机红包的算法

function randomPacket(money,count){
	//先给每个红包赋值为最低0.01元
    let minMoney=0.01;
    let result=new Array(count).fill(minMoney);
    let realMoney=money-count*minMoney;
    for(let i=0;i<count-1;i++){
        if(realMoney>0){
        	//toFixed()返回的是一个字符串,不要忘了用parseFloat()包裹起来
            let value=parseFloat((Math.random()*realMoney).toFixed(2));
            result[i]=result[i]+value;
            realMoney=realMoney-value;
        }
    }
    result[count-1]+=parseFloat(realMoney.toFixed(2));
    return result;
}

let arr=randomPacket(10,10)
let sum1 = arr.reduce((pre, cur) => {
    cur += pre
    return cur
}, 0)
console.log('arr:', arr)
console.log('sum:', parseFloat(sum1.toFixed(10)))

4.柯里化 add(1)(2)(3)

const curry = (fn, ...args) => 
    // 函数的参数个数可以直接通过函数数的.length属性来访问
    args.length >= fn.length // 这个判断很关键!!!
    // 传入的参数大于等于原始函数fn的参数个数,则直接执行该函数
    ? fn(...args)
    /**
     * 传入的参数小于原始函数fn的参数个数时
     * 则继续对当前函数进行柯里化,返回一个接受所有参数(当前参数和剩余参数) 的函数
    */
    : (..._args) => curry(fn, ...args, ..._args);

function add1(x, y, z) {
    return x + y + z;
}
const add = curry(add1);
console.log(add(1, 2, 3));
console.log(add(1)(2)(3));
console.log(add(1, 2)(3));
console.log(add(1)(2, 3));
// 实现一个add方法,使计算结果能够满足如下预期:
add(1)(2)(3) = 6;
add(1, 2, 3)(4) = 10;
add(1)(2)(3)(4)(5) = 15;

function add() {
    // 第一次执行时,定义一个数组专门用来存储所有的参数
    var _args = Array.prototype.slice.call(arguments);

    // 在内部声明一个函数,利用闭包的特性保存_args并收集所有的参数值
    var _adder = function() {
        _args.push(...arguments);
        return _adder;
    };

    // 利用toString隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回
    _adder.toString = function () {
        return _args.reduce(function (a, b) {
            return a + b;
        });
    }
    return _adder;
}

add(1)(2)(3)                // 6
add(1, 2, 3)(4)             // 10
add(1)(2)(3)(4)(5)          // 15
add(2, 6)(1)                // 9

引用:

5.求"对象"深度

如如果"对象"是普通值,返回1,如果"对象"是引用类型,返回2,如果"对象"内为引用类型,且包含其他引用类型,+1并返回

案例:

//例1
1 => 1
//例2
[1, 2, 3] => 2
//例3
{name: 'abc'} => 2
//例4
{
 name: 'abc',
 key: {
     name2: 'cba'
 }
}   =>3
//例5
[1, 2,[2, 3], 1] => 3

代码:

function deep(obj,num=1,max=1){

    if(obj instanceof Object){
        num++;
        for(let key in obj){
            max=Math.max(deep(obj[key],num,max),num);
        } 
    }
    return max
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值