前端面试常见手写代码题集

一、数组去重

//1. 使用Set数据结构
var arr = [3, 2, 4, 2, 1, 2];
var uniqueArr = Array.from(new Set(arr));
console.log(uniqueArr); // 输出:[3, 2, 4, 1]

//2. 使用filter方法
var arr = [3,2, 4, 2, 1, 2];
var uniqueArr = arr.filter(function(item, index, array) {
  return array.indexOf(item) === index;
});
console.log(uniqueArr); // 输出:[3, 2, 4, 1]

二、找到数组最大值

var arr = [1, 5, 3, 9, 2];
var max = Math.max.apply(null, arr);
console.log("Max value in the array: " + max); // 输出:Max value in the array: 9

首先定义了一个数组arr,然后使用Math.max.apply()方法来找到数组中的最大值。apply()方法将Math.max()方法应用于数组arr,并返回最大值。

三、数组快速排序

function quickSort(arr) {
 if (arr.length <= 1) {
    return arr;
  }  
  const pivotIndex = Math.floor(arr.length / 2);
  const pivot = arr.splice(pivotIndex, 1)[0];
  const left = [];
  const 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));
}
const arr = [9, 5, 3, 10, 23, 4, 43];
const sortedArr = quickSort(arr);
console.log(sortedArr); // [3, 4, 5, 9, 10, 23, 43]

快速排序是一种常用的排序算法,它通过选择一个基准元素,将数组分成两个子数组,然后对子数组进行递归排序,最后将两个子数组合并成一个有序数组。在上述示例中,我们选择数组中间的元素作为基准元素,然后将小于基准元素的数放在左边,大于基准元素的数放在右边,最后递归地对左右两个子数组进行排序,最终得到排序后的数组。

四、字符串出现次数最多得字符及次数

function findMostFrequentChar(str) {
  let charMap = {};
  let maxCount = 0;
  let mostFrequentChar = '';
  for (let char of str) {
    if (charMap[char]) {
      charMap[char]++;
    } else {
      charMap[char] = 1;
    }
    if (charMap[char] > maxCount) {
      maxCount = charMap[char];
      mostFrequentChar = char;
    }
  }
  return {
    char: mostFrequentChar,
    count: maxCount
  };
}
let str = "abcaabbcc";
let result = findMostFrequentChar(str);
console.log( result.char);//a
console.log( result.count);//3



首先创建了一个空对象`charMap`,用于存储每个字符出现的次数。然后,遍历字符串中的每个字符,如果字符已经在`charMap`中存在,则将其对应的计数加1;否则,在`charMap`中新增该字符,并将计数初始化为1。同时,还维护了两个变量`maxCount`和`mostFrequentChar`,用于记录出现次数最多的字符和其出现的次数。遍历完成后,返回一个包含最频繁字符和次数的对象。

五、字符串转驼峰

const str = "this_is_an_abc";
const words = str.split('_');
const camelCase = words.map((word, index) => {
  if (index === 0) {
    return word;
  } else {
    return word.charAt(0).toUpperCase() + word.slice(1);
  }
}).join('');

console.log(camelCase); // 输出:thisIsAnAbc

 六、数组扁平化

//1. 使用递归和concat方法:
function flatten(arr) {
  return arr.reduce(function (result, item) {
    if (Array.isArray(item)) {
      return result.concat(flatten(item));
    } else {
      return result.concat(item);
    }
  }, []);
}
var arr = [1, [2, [3, 4]]];
console.log(flatten(arr)); // 输出:[1, 2, 3, 4]

//2. 使用split和toString方法:
function flatten(arr) {
  return arr.toString().split(',').map(function (item) {
    return parseInt(item);
  });
}
var arr = [1, [2, [3, 4]]];
console.log(flatten(arr)); // 输出:[1, 2, 3, 4]

七、柯里化

function curry(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn.apply(this, args);
    } else {
      return function (...moreArgs) {
        return curried.apply(this, args.concat(moreArgs));
      };
    }
  };
}
function sum(a, b, c) {
  return a + b + c;
}
var curriedSum = curry(sum);
console.log(curriedSum(1)(2)(3)); // 输出:6

定义了一个`curry`函数,它接受一个函数作为参数,并返回一个新的柯里化函数。这个柯里化函数可以接受任意数量的参数,并在参数数量达到原函数所需参数数量时,调用原函数并返回结果。如果参数数量不足,则返回一个新的柯里化函数,等待更多的参数。使用`curry`函数将`sum`函数转换为柯里化函数`curriedSum`。然后可以像调用普通函数一样,使用多个括号来传递参数。在最后一次调用中,传递了3个参数,得到了最终的结果6。

八、浅拷贝

//1. 使用for...in循环遍历对象属性,将属性值复制到新对象中。
var a = { name: '我是a' };
function simpleCopy(obj) {
  var newObj = {};
  for (let key in obj) {
    newObj[key] = obj[key];
  }
  return newObj;
}
var b = simpleCopy(a);
b.name = '我是b';
console.log(a.name); // 输出:我是a
console.log(b.name); // 输出:我是b

//2. 使用箭头函数和hasOwnProperty方法判断是否为自身属性,然后将属性值复制到新对象中。
var shallClone = obj => {
  var res = {};
  for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
      res[key] = obj[key];
    }
  }
  return res;
}
var obj = {
  type: 'animal',  color: 'red',
  desc: {
    eyes: '2',
    body: 'strong'
  }
};
var newObj = shallClone(obj);
obj.desc.eyes = 3;
console.log(obj.desc.eyes); // 输出:3
console.log(newObj.desc.eyes); // 输出:2
console.log(obj.desc === newObj.desc); // 输出:true,浅拷贝指向同一地址

九、深拷贝

//1. 使用JSON.parse和JSON.stringify方法进行深拷贝:
let a = {a: 1, b: 2};
let b = JSON.parse(JSON.stringify(a));
a.a = 11;
console.log(a); // 输出:{a: 11, b: 2}
console.log(b); // 输出:{a: 1, b: 2}

//2. 使用递归函数实现深拷贝:
function deepClone(source) {
  if (typeof source !== 'object' || source == null) {
    return source;
  }
  const target = Array.isArray(source) ? [] : {};
  for (const key in source) {
    if (Object.prototype.hasOwnProperty.call(source, key)) {
      if (typeof source[key] === 'object' && source[key] !== null) {
        target[key] = deepClone(source[key]);
      } else {
        target[key] = source[key];
      }
    }
  }
  return target;
}

十、斐波那契

function fib(num) {
  if (num < 1) return 0;
  else if (num == 1 || num == 2) return 1;
  return fib(num - 1) + fib(num - 2);
}
console.log(fib(6)); // 输出:8

使用递归的方式来计算斐波那契数列的第n个数字。当n小于1时,返回0;当n等于1或2时,返回1;否则,返回前两个数字的和。在这个例子中,计算了斐波那契数列的第6个数字,结果为8。

十一、回文字符串

function isPalindrome(str) {
  // 去除字符串中的非字母和数字字符
  var cleanStr = str.replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
  // 反转字符串
  var reversedStr = cleanStr.split("").reverse().join("");
  // 判断反转后的字符串是否与原字符串相等
  if (cleanStr === reversedStr) {
    return true;
  } else {
    return false;
  }
}

十二、虚拟DOM

// 定义虚拟DOM类
class VNode {
  constructor(tag, props, children) {
    this.tag = tag; // 节点标签
    this.props = props; // 节点属性
    this.children = children; // 子节点
  }
  // 渲染虚拟DOM为真实DOM
  render() {
    const element = document.createElement(this.tag); // 创建真实DOM节点
    // 设置节点属性
    for (const key in this.props) {
      element.setAttribute(key, this.props[key]);
    }
    // 渲染子节点
    for (const child of this.children) {
      if (child instanceof VNode) {
        element.appendChild(child.render()); // 递归渲染子节点
      } else {
        element.appendChild(document.createTextNode(child)); // 渲染文本节点
      }
    }
    return element;
  }
}
// 创建虚拟DOM对象
const vnode = new VNode('div', { id: 'myDiv' }, [
  new VNode('h1', {}, ['Hello, World!']),
  'This is a text node'
]);
// 渲染虚拟DOM为真实DOM并添加到页面中
document.body.appendChild(vnode.render());

定义一个`VNode`类,用于表示虚拟DOM节点。通过创建`VNode`对象,可以构建一个虚拟DOM树。然后,通过调用`render`方法,将虚拟DOM渲染为真实DOM,并将其添加到页面中。

  • 13
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值