Javascript手写题合集(1-10)

1. 数组去重基础版

function unique_1(arr) {
  return [...new Set(arr)];
}
function unique_2(arr) {
  return arr.filter((item, index) => {
    return arr.indexOf(item) === index;
  });
}
function unique_3(arr) {
  return arr.reduce((unique,item)=>{
    return unique.includes(item)?unique:[...unique,item]
  },[]);
}

2. 数组去重进阶版

/**
 * @description: 检查两个对象 obj1 和 obj2 是否值相等
 * @param {*} obj1
 * @param {*} obj2
 * @return {*}
 */
function checkObj(obj1, obj2) {
  // 指向同一内存
  if (obj1 === obj2) return true;
  let arr1 = Object.keys(obj1),
    arr2 = Object.keys(obj2);
  // 判断属性值是否相等
  if (arr1.length != arr2.length) return false;
  for (const k in arr1) {
    if (typeof arr1[k] == "object" || typeof arr2[k] == "object") {
      if (!checkObj(arr1[k], arr2[k])) return false;
    } else if (arr1[k] !== arr2[k]) {
      return false;
    }
  }
  return true;
}
/**
 * @description: 在数组原型上写方法
 * @param {*} itemObj
 * @return {*}
 */
Array.prototype.includesObj = function (itemObj) {
  let flag = false;
  for (let i = 0; i < this.length; i++) {
    if (checkObj(this[i], itemObj)) {
      flag = true;
      break;
    }
  }
  return flag;
};
/**
 * @description: 针对对象数组,且可能出现对象引用的问题
 * @param {*} arr
 * @return {*}
 */
function uniqSpecial(arr) {
  const result = [];
  for (let i = 0; i < arr.length; i++) {
    // 如果不存在
    if (!result.includesObj(arr[i])) result.push(arr[i]);
  }
  return result;
}

3. 数组清空

// 1. 数组的length属性
let arr = [1, 2, 3];
arr.length = 0;

// 2. splice方法
arr = [1, 2, 3];
arr.splice(0, arr.length)

// 3. 新建一个新的空数组覆盖原来的
arr = [1, 2, 3];
arr = [];

// 4. shift
arr = [1, 2, 3];
while(arr.length > 0) {
    arr.shift();
}
// 4. pop
arr = [1, 2, 3];
while(arr.length > 0) {
  arr.pop();
}
// 5. slice
arr = [1, 2, 3];
arr = arr.slice(arr.length);

// 6. filter
arr = [1, 2, 3];
arr = arr.filter(() => false);

4. 数组求交

function intersections(arr1, arr2) {
  const set = [...new Set(arr1)]
  return set.filter(item => arr2.includes(item))
}

5. LazyMan

实现一个LazyMan,可以按照以下方式调用:
LazyMan(“Hank”)输出:
Hi! This is Hank!

LazyMan(“Hank”).sleep(10).eat(“dinner”)输出
Hi! This is Hank!
//等待10秒…
Wake up after 10
Eat dinner~

LazyMan(“Hank”).eat(“dinner”).eat(“supper”)输出
Hi This is Hank!
Eat dinner~
Eat supper~

LazyMan(“Hank”).sleepFirst(5).eat(“supper”)输出
//等待5秒
Wake up after 5
Hi This is Hank!
Eat supper
以此类推。

function lazyman(name) {
  const taskQueue = []; // 任务队列

  function sayHi() {
    taskQueue.push(() => console.log(`Hi! This is ${name}!`));
    return this;
  }

  function eat(something) {
    taskQueue.push(() => console.log(`Eat ${something}~`));
    return this;
  }

  function sleep(time) {
    taskQueue.push(_sleep(time));
    return this;
  }

  function sleepFirst(time) {
    taskQueue.unshift(_sleep(time));
    return this;
  }

  function _run() {
    taskQueue.forEach(task => task());
  }

  function _sleep(time) {
    return () => {
      const start = +new Date();
      while (start + time * 1000 > +new Date());
      console.log(`Wake up after ${time}s`);
    };
  }
  sayHi()
  // 异步,最后再依次执行
  setTimeout(_run, 0);

  return {
    eat,
    sleep,
    sleepFirst
  };
}

// 测试
lazyman("Hank").sleep(10).eat("dinner");
lazyman("Hank").eat("dinner").eat("supper");
lazyman("Hank").sleepFirst(5).eat("supper");

6. 生成不重复随机数组

function randomUniqueArr(len, min, max) {
  if (!len || len <= 0) return [];
  const _min = Math.min(min, max);
  const _max = Math.max(min, max);

  // 特殊情况处理
  if (_max - _min + 1 < len) {
    throw new Error("Range is too small to generate the required number of unique elements");
  }

  // 生成从 _min 到 _max 的所有整数数组
  const rangeArray = new Array(_max - _min + 1).fill(null).map((_, idx) => idx + _min);

  // Fisher-Yates 洗牌算法
  for (let i = rangeArray.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [rangeArray[i], rangeArray[j]] = [rangeArray[j], rangeArray[i]];
  }

  // 返回前 len 个元素
  return rangeArray.slice(0, len);
}

7. 实现async/await

// 完全版
function asyncToGenerator(generatorFunc) {
    return function () {
        let gen = generatorFunc.apply(this, arguments)
        return new Promise((resolve, reject) => {
            function step(name, arg) {
                let generatorResult;
                try {
                    generatorResult = gen[name](arg)
                } catch (err) {
                    reject(err)
                }
                const { value, done } = generatorResult
                if (done) {
                    resolve(value)
                } else {
                    Promise.resolve(value).then(
                        (val) => {
                            step('next', val)
                        },
                        (err) => {
                            step('throw', err)
                        }
                    );
                }
            }
            step('next')
        })
    }
}

```
# 8. 实现indexOf
```js
String.prototype.myIndexOf = function myIndexOf(searchvalue, start = 0) {
  if (typeof searchvalue !== "string" || start < 0 || start > this.length) {
    return -1;
  };
  for (let index = start; index < this.length; index++) {
    if (this[index] === searchvalue[0]) {
      let len = searchvalue.length;
      let i = 0;
      while (i < len && this[index + i] === searchvalue[i]) {
        i++;
      }
      if (i === len) return index;
    }
  }
  return -1;
};
```
# 9. 实现Promise.all
```js
let PromiseAll = function (prams) {
  return new Promise((resolve, reject) => {
    try {
      const results = []
      let count = 0
      let fulfilledCount = 0
      for (const p of prams) {
        let i = count
        count++
        Promise.resolve(p).then((data) => {
          fulfilledCount++
          results[i] = data
          if (fulfilledCount === count) {
            resolve(results)
          }
        },reject)
      }
      if(count === 0) {
        resolve(results)
      }
    } catch (error) {
      reject(error)
    }
  }
  )
}

```
# 10.树形结构转列表
```js
function treeToList(data) {
  let res = [];
  const dfs = (tree) => {
    tree.forEach((item) => {
      if (item.children) {
        dfs(item.children);
        delete item.children;
      }
      res.push(item);
    });
  };
  dfs(data);
  return res;
}
```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端之仙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值