javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > JS面试

JS面试必备之手写instanceof,深拷贝,节流和防抖

作者:feelingHy

JavaScript如何实现手写instanceof、深拷贝、节流、防抖也是面试时常常考到的知识点,这篇文章为大家进行了详细介绍,需要的可以参考一下

一、instanceof 的实现

使用 instanceof 操作符,如果一个实例的原型链中出现过相应的构造函数的原型,则 instanceof 返回 true。

instanceof 主要的实现原理就是只要右边变量的 prototype 在左边变量的原型链上即可。 因此,instanceof 在查找的过程中会遍历左边变量的原型链,直到找到右边变量的 prototype,如果查找失败,则会返回 false,告诉我们左边变量并非是右边变量的实例。

function instanceof1(L,R) {
  L = L.__proto__;

  while(L != null) {
    if(L === R.prototype) {
      return true;
    }
    L = L.__proto__;
  }
  return false;
}

二、浅拷贝

// 浅拷贝
function shallowClone(obj) {
  const result = {};
  for(let key in obj) {
    console.log('ddddd',key);
    if(obj.hasOwnProperty(key)) {
      result[key] = obj[key];
    }
  }
  return result;
}

测试代码:

let obj = {
  b: {
    c: [1, 5, 11, 23, 422]
  },
  d: function() {
    console.log('hello world');
  }
};
const result = shallowClone(obj);
console.log(result);
const newObj = Object.assign({},obj);
console.log(newObj);

三、深拷贝

// 深拷贝
function deepClone(obj) {
  if(typeof obj != 'object' || obj == null) {
    return obj;
  }
  const result = Array.isArray(obj) ? [] : {};
  for(let key in obj) {
    // 自有属性
    if(obj.hasOwnProperty(key)) {
      const type = typeof obj[key];
      if(type == 'object' && obj[key] != null) {
        result[key] = deepClone(obj[key]);
      } else {
        result[key] = obj[key];
      }
    }
  }
  return result;
}

测试代码:

var data = {
  age: 18,
  name: "liuruchao",
  education: ["小学", "初中", "高中", "大学", undefined, null],
  likesFood: new Set(["fish", "banana"]),
  friends: [
        { name: "summer",  sex: "woman"},
        { name: "daWen",   sex: "woman"},
        { name: "yang",    sex: "man" }  ],
  work: {
          time: "2019",
          project: { name: "test",obtain: ["css", "html", "js"]}
        },
  play: function() {    console.log("玩滑板");  }
}
console.log(deepClone(data));

解决循环引用问题:

// 解决循环引用问题
function deepClone2(obj, hash = new WeakMap()) {
  const type = typeof obj;
  if(type != 'object' || obj == null) {
    return obj;
  }
  if(hash.has(obj)) {
    return hash.get(obj);
  }
  const result = Array.isArray(obj) ? [] : {};
  for(let key in obj) {
    if(obj.hasOwnProperty(key)) {
      if(typeof obj[key] != 'object' || obj[key] == null) {
        result[key] = obj[key];
      } else {
        // 首次调用时,weakMap为空,不会走上面那个if(hash.has())语句,如果待拷贝对象中有属性也为对象时,
        // 则将该待拷贝对象存入weakMap中,此时的健值和健名都是对该待拷贝对象的引用
        hash.set(obj, obj)
        result[key] = deepClone2(obj[key], hash);
      }
    }
  }
  return result;
}

测试代码:

var data2 = {
  name: 'foo',
  child: null,
}
data2.child = data2;
console.log(deepClone2(data2));

四、函数防抖

使用场景:resize、scroll、输入框内容校验等。

function debounce(handle,wait) {
  let timer = null;
  return function () {
    if(timer != null) {
      clearTimeout(timer);
    }
    timer = setTimeout(handle, wait);
  }
}

五、节流

当持续触发事件时,保证一定时间内只调用一次事件处理函数。通俗解释就比如:我们把水龙头打开,水哗哗的往外流,秉着节约的原则,我们要把水龙头关小,最好是如我们的心愿按照一定的规律,在某个时间内一滴一滴的往下滴。

时间戳版本:

function throttle (handle,wait) {
  let prev = Date.now();
  return function() {
    let current = Date.now();
    if(current - prev >= wait) {
      handle();
      prev = Date.now();
    }
  }
}

定时器版本:

function throttle1(handle, wait) {
  let timer = null;
  return function() {
    if(!timer) {
      timer = setTimeout(() => {
        handle();
        timer = null;
      },wait);
    }
  }
}

定时器 + 时间戳版本:

function throttle2 (handle, wait) {
  let pre = Date.now();
  let timer = null;
  return function() {
    let current = Date.now();
    let remaining = wait - (current - pre);
    clearTimeout(timer);
    if(remaining <= 0) {
      handle();
      pre = Date.now();
    } else {
      timer = setTimeout(handle, remaining);
    }
  }
}

节流和防抖总结:

以上就是JS面试必备之手写instanceof,深拷贝,节流和防抖的详细内容,更多关于JS面试的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文