前端面试-JS手写题(慢更)

96 阅读3分钟

手写实现bind

function fn() {
  console.log(this);
  // console.log([...arguments]);
}

Function.prototype.bind2 = function (context) {
  // 把this保存起来
  let self = this;
  // 入参保存
  const args = [...arguments].slice(1);
  // 构建返回函数
  const fn2 = function () {
      // 入参保存
    const innerArgs = [...arguments];
    // 如果是作为构造函数 则不重新指定
    const tempContext = this instanceof fn2 ? this : context;
    return self.apply(tempContext, args.concat(innerArgs));
  }

  return fn2;
}

// 测试代码
const obj = { name: '110', age: '18' }

fn.prototype.sex = '男';

let person = fn.bind(obj);
let person2 = new person(obj);

// fn.bind2(obj, 1, 2, 3)(119, 20);
console.log(person2.sex);

手写实现new

new 关键字会进行如下的操作:

  1. 创建一个空的简单 JavaScript 对象(即  {} );
  2. 为步骤 1 新创建的对象添加属性  __proto__ ,将该属性链接至构造函数的原型对象;
  3. 将步骤 1 新创建的对象作为 this 的上下文;
  4. 如果该函数没有返回对象,则返回 this
function mayNew(Fn) {
  // 校验
  if (typeof Fn !== 'function') throw new TypeError('this is not a constructor')
  // 创建一个空对象
  const obj = {};
  // 入参
  const args = [...arguments].slice(1);
  // 为创建的对象添加属性__proto__,将该属性链接至构造函数的原型对象;
  obj.__proto__ = Fn.prototype;
  // 将创建的对象作为上下文
  const res = Fn.call(obj, ...args);
  // 返回结果处理
  return res ? res : obj;
}

function Fn(name, age) {
  this.name = name;
  this.age = age
}

Fn.prototype.say = function () {
  console.log('Fn.prototype.say')
}

// 测试1
const me = mayNew(Fn, 110, 26);
console.log(me);
me.say();
// 测试2
const me2 = mayNew(Fn, 119, 27);
console.log(me2);
me2.say();

手写一个类型判断函数

function demo(arg) {
  // NaN类型判断
  if (isNaN(arg)) return 'NaN';
  // 数组 对象 null 日期 正则都可以
  return Object.prototype.toString.call(arg).slice(8, -1).toLowerCase();
}

手写节流防抖

节流

function throttle(fn, delay) {
  // 定义初始时间为0
  let t1 = 0;
  return function () {
    // 函数当前执行时间
    const t2 = Date.now();
    // 函数执行时间判断
    if (t2 - t1 > delay) {
      t1 = t2;
      // 改变this指向
      fn.call(this, ...arguments);
    }
  }
}

function fn() {
  console.log('函数被执行');
}
// 测试
const tFn = throttle(fn, 200);

tFn();
const tt = setInterval(tFn, 100);

setTimeout(() => {
  clearInterval(tt);
}, 5000)

防抖

function debounce(fn, delay){
  // 定时器ID
  let tId;
  return function(){
    // 每次执行先清除定时器
    clearTimeout(tId)
    tId = setTimeout(()=>{
      fun.call(this, ...arguments)
    },delay)
  }
}


// 触发时立即执行一次
function debounce2(fn, delay) {
  // 定时器ID
  let tId;
  return function () {
    const immediate = !tId;
    // 每次执行清除上一次设定的定时器
    clearTimeout(tId);
    // 重新设定定时器
    tId = setTimeout(() => {
      tId = null;
      if (!immediate) fn.call(this, ...arguments);
    }, delay);
    // 立即执行
    if (immediate) {
      fn.call(this, ...arguments);
    };

  }
}

function fn(arg) {
  console.log('函数被执行', arg);
}
// 测试
const tFn = debounce(fn, 500);
tFn(1);
tFn(2);
tFn(3);
const tt = setInterval(() => tFn('z'), 1000);

setTimeout(() => {
  clearInterval(tt);
  console.log('定时器已被清除');
}, 5000)

手写Promise

class MyPromise {
        constructor(executor) {
          this.state = "pending";
          this.value = undefined;
          this.handlers = [];

          const resolve = value => {
            if (this.state === "pending") {
              this.state = "fulfilled";
              this.value = value;
              this.handlers.forEach(handler => this.executeHandler(handler));
              this.handlers = [];
            }
          };

          const reject = reason => {
            if (this.state === "pending") {
              this.state = "rejected";
              this.value = reason;
              this.handlers.forEach(handler => this.executeHandler(handler));
              this.handlers = [];
            }
          };
          // 拦截 erro
          try {
            executor(resolve, reject);
          } catch (error) {
            reject(error);
          }
        }
        // 事件处理
        executeHandler(handler) {
          const { onFulfilled, onRejected, resolve, reject } = handler;

          try {
            if (this.state === "fulfilled") {
              if (typeof onFulfilled === "function") {
                const result = onFulfilled(this.value);
                resolve(result);
              } else {
                resolve(this.value);
              }
            } else if (this.state === "rejected") {
              if (typeof onRejected === "function") {
                const result = onRejected(this.value);
                resolve(result);
              } else {
                reject(this.value);
              }
            }
          } catch (error) {
            reject(error);
          }
        }

        then(onFulfilled, onRejected) {
          return new MyPromise((resolve, reject) => {
            const handler = { onFulfilled, onRejected, resolve, reject };

            if (this.state === "pending") {
              // 保存回调函数handlers
              this.handlers.push(handler);
            } else {
              this.executeHandler(handler);
            }
          });
        }

        catch(onRejected) {
          return this.then(undefined, onRejected);
        }

        static resolve(value) {
          return new MyPromise(resolve => resolve(value));
        }

        static reject(reason) {
          return new MyPromise((_, reject) => reject(reason));
        }

        static all(promises) {
          return new MyPromise((resolve, reject) => {
            const results = [];
            let completedCount = 0;

            const processPromise = (index, value) => {
              results[index] = value;
              completedCount++;

              if (completedCount === promises.length) {
                resolve(results);
              }
            };

            promises.forEach((promise, index) => {
              if (promise instanceof MyPromise) {
                promise
                  .then(value => processPromise(index, value))
                  .catch(reject);
              } else {
                processPromise(index, promise);
              }
            });
          });
        }

        static race(promises) {
          return new MyPromise((resolve, reject) => {
            promises.forEach(promise => {
              if (promise instanceof MyPromise) {
                promise.then(resolve).catch(reject);
              } else {
                resolve(promise);
              }
            });
          });
        }
      }

      const promise2 = new MyPromise((resolve, reject) => {
        resolve("Promise 2 resolved");
      });

      promise2
        .then(value => {
          console.log(value); // 输出: "Promise 2 resolved"
          return "Chain value 1";
        })
        .then(value => {
          console.log(value); // 输出: "Chain value 1"
          throw new Error("Error occurred");
        })
        .catch(error => {
          console.log(error.message); // 输出: "Error occurred"
          return "Chain value 2";
        })
        .then(value => {
          console.log(value); // 输出: "Chain value 2"
        });