当前位置:   article > 正文

32个手写JS,巩固你的JS基础(面试高频)

手写js

作为前端开发,JS是重中之重,最近结束了面试的高峰期,基本上offer也定下来了就等开奖,趁着这个时间总结下32个手写JS问题,这些都是高频面试题,希望对你能有所帮助。

关于源码都紧遵规范,都可跑通MDN示例,其余的大多会涉及一些关于JS的应用题和本人面试过程

01.数组扁平化

数组扁平化是指将一个多维数组变为一个一维数组

  1. const arr = [1, [2, [3, [4, 5]]], 6];
  2. // => [1, 2, 3, 4, 5, 6]

方法一:使用flat()

const res1 = arr.flat(Infinity);

方法二:利用正则

const res2 = JSON.stringify(arr).replace(/\[|\]/g, '').split(',');

但数据类型都会变为字符串

方法三:正则改良版本

const res3 = JSON.parse('[' + JSON.stringify(arr).replace(/\[|\]/g, '') + ']');

方法四:使用reduce

  1. const flatten = arr => {
  2. return arr.reduce((pre, cur) => {
  3. return pre.concat(Array.isArray(cur) ? flatten(cur) : cur);
  4. }, [])
  5. }
  6. const res4 = flatten(arr);

方法五:函数递归

  1. const res5 = [];
  2. const fn = arr => {
  3. for (let i = 0; i < arr.length; i++) {
  4. if (Array.isArray(arr[i])) {
  5. fn(arr[i]);
  6. } else {
  7. res5.push(arr[i]);
  8. }
  9. }
  10. }
  11. fn(arr);

02.数组去重

  1. const arr = [1, 1, '1', 17, true, true, false, false, 'true', 'a', {}, {}];
  2. // => [1, '1', 17, true, false, 'true', 'a', {}, {}]

方法一:利用Set

const res1 = Array.from(new Set(arr));

方法二:两层for循环+splice

  1. const unique1 = arr => {
  2. let len = arr.length;
  3. for (let i = 0; i < len; i++) {
  4. for (let j = i + 1; j < len; j++) {
  5. if (arr[i] === arr[j]) {
  6. arr.splice(j, 1);
  7. // 每删除一个树,j--保证j的值经过自加后不变。同时,len--,减少循环次数提升性能
  8. len--;
  9. j--;
  10. }
  11. }
  12. }
  13. return arr;
  14. }

方法三:利用indexOf

  1. const unique2 = arr => {
  2. const res = [];
  3. for (let i = 0; i < arr.length; i++) {
  4. if (res.indexOf(arr[i]) === -1) res.push(arr[i]);
  5. }
  6. return res;
  7. }

当然也可以用include、filter,思路大同小异。

方法四:利用include

  1. const unique3 = arr => {
  2. const res = [];
  3. for (let i = 0; i < arr.length; i++) {
  4. if (!res.includes(arr[i])) res.push(arr[i]);
  5. }
  6. return res;
  7. }

方法五:利用filter

  1. const unique4 = arr => {
  2. return arr.filter((item, index) => {
  3. return arr.indexOf(item) === index;
  4. });
  5. }

方法六:利用Map

  1. const unique5 = arr => {
  2. const map = new Map();
  3. const res = [];
  4. for (let i = 0; i < arr.length; i++) {
  5. if (!map.has(arr[i])) {
  6. map.set(arr[i], true)
  7. res.push(arr[i]);
  8. }
  9. }
  10. return res;
  11. }

03.类数组转化为数组

类数组是具有length属性,但不具有数组原型上的方法。常见的类数组有arguments、DOM操作方法返回的结果。

方法一:Array.from

Array.from(document.querySelectorAll('div'))

方法二:Array.prototype.slice.call()

Array.prototype.slice.call(document.querySelectorAll('div'))

方法三:扩展运算符

[...document.querySelectorAll('div')]

方法四:利用concat

Array.prototype.concat.apply([], document.querySelectorAll('div'));

04.Array.prototype.filter()

  1. Array.prototype.filter = function(callback, thisArg) {
  2. if (this == undefined) {
  3. throw new TypeError('this is null or not undefined');
  4. }
  5. if (typeof callback !== 'function') {
  6. throw new TypeError(callback + 'is not a function');
  7. }
  8. const res = [];
  9. // 让O成为回调函数的对象传递(强制转换对象)
  10. const O = Object(this);
  11. // >>>0 保证len为number,且为正整数
  12. const len = O.length >>> 0;
  13. for (let i = 0; i < len; i++) {
  14. // 检查i是否在O的属性(会检查原型链)
  15. if (i in O) {
  16. // 回调函数调用传参
  17. if (callback.call(thisArg, O[i], i, O)) {
  18. res.push(O[i]);
  19. }
  20. }
  21. }
  22. return res;
  23. }

05.Array.prototype.map()

  1. Array.prototype.map = function(callback, thisArg) {
  2. if (this == undefined) {
  3. throw new TypeError('this is null or not defined');
  4. }
  5. if (typeof callback !== 'function') {
  6. throw new TypeError(callback + ' is not a function');
  7. }
  8. const res = [];
  9. // 同理
  10. const O = Object(this);
  11. const len = O.length >>> 0;
  12. for (let i = 0; i < len; i++) {
  13. if (i in O) {
  14. // 调用回调函数并传入新数组
  15. res[i] = callback.call(thisArg, O[i], i, this);
  16. }
  17. }
  18. return res;
  19. }

06.Array.prototype.forEach()

forEach跟map类似,唯一不同的是

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号