前端常见面试题

91 阅读2分钟

手动实现一个call方法

 //实现call方法
    Function.prototype.myCall = function (context, ...rest) {
      //对于context为null或者没传时的处理
      context = context || window;
      // 将当前的this 暂存于context对象中。此时的this为封装类将来要绑定的函数的原型对象,下面调用的getName方法挂在this.prototype上。
      context.fn = this;
      // 以context对象上的属性的方式执行函数(此时触发隐式绑定)
      let ret = context.fn(...rest);
      //将挂在上面的中间属性fn 删除。其作用只是为了帮助我们改变this,同时执行函数所用。
      delete context.fn;
      return ret;
    }
// 测试代码
    let obj = {
      name: 1
    }

    function getName(a, b, c) {
      return this;
    }
    let ret = getName.myCall(obj, 2, 3, 4);
    console.log(ret);

手写call方法

//实现call方法
    Function.prototype.myCall = function (context, ...rest) {
      //对于context为null或者没传时的处理
      context = context || window;
      // 将当前的this 暂存于context对象中。此时的this为封装类将来要绑定的函数的原型对象,下面调用的getName方法挂在this.prototype上。
      context.fn = this;
      // 以context对象上的属性的方式执行函数(此时触发隐式绑定)
      let ret = context.fn(...rest);
      //将挂在上面的中间属性fn 删除。其作用只是为了帮助我们改变this,同时执行函数所用。
      delete context.fn;
      return ret;
    }
// 测试代码
    let obj = {
      name: 1
    }
​
    function getName(a, b, c) {
      return this;
    }
    let ret = getName.myCall(obj, 2, 3, 4);
    console.log(ret);
​
​

手动实现深拷贝

// 深拷贝
 const deepClone = (obj) => {
      // 使用递归进行拷贝
      let deepObj = Array.isArray(obj) ? [] : {};
      if (obj && typeof obj === "object") {
        for (const key in obj) {
          if (obj.hasOwnProperty(key)) {
            if (typeof key === "object") {
              deepObj[key] = deepClone(obj[key]);
            } else {
              deepObj[key] = obj[key];
            }
          }
        }
      }
      return deepObj;
    };
// 测试代码
 const obj = {
      name: 1,
      age: 2,
      like: {
        sing: "changge",
        dance: "tiaowu",
        play: {
          wanshouji: 1,
          xiedaima: 2,
        },
      },
    };
​
    const newObj = deepClone(obj);
    console.log(newObj);

手写promise函数

    const PENDING = 'pending';
    const FULFILLED = 'fulfilled';
    const REJECT = 'reject';
    function myPromise(fn) {
      let _this = this;
      this.state = PENDING;
      this.value = undefined;
      this.reason = undefined;
      this.onFulfillList = [];
      this.onRejectList = [];
      function reslove(value) {
        _this.state = FULFILLED;
        _this.value = value;
        _this.onFulfillList.forEach((item) => item(value));
      }
      function reject(reason) {
        _this.state = REJECT;
        _this.reason = reason;
        _this.onRejectList.forEach((item) => item(reason));
      }
      try {
        fn(reslove, reject);
      } catch (error) {
        reject(error);
      }
      myPromise.prototype.then = function(res, rej) {
        if (this.state === 'fulfilled') {
          typeof res === 'function' && res(this.value);
        }
        if (this.state === 'reject') {
          typeof rej === 'function' && rej(this.reason);
        }
        if (this.state === 'pending') {
          typeof res === 'function' && this.onFulfillList.push(res);
          typeof rej === 'function' && this.onRejectList.push(rej);
        }
      };
​
​

字符串段横行命名替换成驼峰

// 方法 1
function humpString(str) {
      if (str) {
        return str.replace(/_\w/g, (lineStr) => {
          return lineStr.slice(1).toUpperCase();
        });
      }
    }
// 方法 2
function humpString(str) {
      if (str) {
        const strArr = str.split("_");
        for (let i = 1; i < strArr.length; i++) {
          strArr[i] = strArr[i].slice(0, 1).toUpperCase() + strArr[i].slice(1);
        }
        return strArr.join("");
      }
    }

new操作符的实现


function _new(constructor, ...args) {
     // 判断类型
    if (typeof constructor !== "function") {
      throw new Error("constructor must be a function");
    }
    // 1 新建空对象实例
    let obj = new Object();
    // 构建原型链
    obj.__proto__ = Object.create(constructor.prototype);
    // 调用构造函数并判断返回值
    let res = constructor.apply(obj, args);
    let isObject = typeof res === "object" && res !== null;
    let isFunction = typeof res === "function";
    // 如果有返回值且返回值是对象类型,那么就将它作为返回值,否则就返回之前新建的对象
    return isObject || isFunction ? res : obj;
    }