JavaScript高级

91 阅读4分钟

原型和原型链

  • 1.理解原型设计模式以及JavaScript中的原型规则 解:就是创建一个共享的原型,通过拷贝这个原型来创建新的类,用于创建重复的对象,带来性能上的提升。
  • 2.instanceof的底层实现原理,手动实现一个instanceof 解: instanceof的底层实现原理
function instanceof_S(left, right) {
  let mg = right.prototype
  while (true) {
      if (left === null) {
          return false
      }
      if (left === mg) {
          return true
      }
      left = left.__proto__
  }
}
  • 4.实现继承的几种方式以及他们的优缺点 解:
  • 5.new关键字做了那几件事 解:
    1- 创建了一个空对象
    2- 将this指向了这个实例对象
    3- 执行了构造函数里的代码
    4- 返回了一个新对象
  • 6.理解es6 class构造以及继承的底层实现原理

闭包

1.理解词法作用域和动态作用域

2.理解JavaScript的作用域和作用域链 作用域:作用域是在运行时代码中的某些特定部分中变量,函数和对象的可访问性(作用于决定了变量中的可访问性) 作用域链: 在当前作用域中没有找到会一直往上层作用域找,这一过程称为作用域链 3.理解JavaScript的执行上下文栈,可以应用堆栈信息快速定位问题

堆栈信息快速定位问题
var a = {
	x: 10
}
var b = a
b.x = 20
console.log(a) // {x: 20}
因为引用类型赋值时只会产生浅拷贝,赋值的是指针,而数据实际存储于堆中,因此修改B数据时实际把A数据的内容修改了!

4.this的的四种指向问题
解:
1- 普通函数中: 指向window
2- 构造函数中: 指向new的这个实例对象
3- 对象的函数中: 指向的是这个对象
4- 箭头函数中: 指向的是上层的作用域
5.闭包的实现原理和作用,可以列举几个开发中闭包的实际应用
解:
原理:函数中使用了另一个函数的变量,导致变量不能释放!
优点: 私有化数据 方便调用上下文中声明的局部变量
缺点: 堆栈溢出和内存泄漏
6. 理解堆栈溢出和内存泄漏的原理,如何防止内存泄漏
解:内存泄漏:变量没有被垃圾回收机制回收,变量得不到释放,内存泄漏
堆栈溢出:没有可以分配的内存了
防止内存泄漏:减少全局变量的声明 减少使用闭包

JavaScript深拷贝的几种方法

解:

什么是防抖和节流?有什么区别?如何实现

解:】防抖节流
防抖: 触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间
节流: 触发高频事件后n秒内函数只会执行一次,稀释函数的执行效率

防抖案例
function debounce(fn) {
  let timeout = null;
  clearTimeout(timeout); // 每当用户输入的时候把前一个 setTimeout clear 掉
  return function () {
      timeout = setTimeout(() => { // 然后又创建一个新的 setTimeout, 这样就能保证输入字符后的 interval 间隔内如果还有字符输入的话,就不会执行 fn 函数
          fn.apply(this, arguments);
         //加上 apply 确保 在 sayHi 函数里的 this 指向的是 input对象(不然就指向 window 了)。这里的箭头函数依旧是指向 input 对象。
      }, 500);
  	}
  }
function sayHi() {
  console.log('防抖成功');
}
var inp = document.getElementById('inp');
inp.addEventListener('input', debounce(sayHi)); // 防抖
节流案例
function throttle(fn) {
  let canRun = true; // 通过闭包保存一个标记
  return function () {
  if (!canRun) return; // 在函数开头判断标记是否为true,不为true则return
  canRun = false; // 立即设置为false
  setTimeout(() => { // 将外部传入的函数的执行放在setTimeout中
    fn.apply(this, arguments);
    // 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。当定时器没有执行的时候标记永远是false,在开头被return掉
    canRun = true;
    }, 500);
  };
}
function sayHi(e) {
console.log(e.target.innerWidth, e.target.innerHeight);
}
window.addEventListener('resize', throttle(sayHi));
ES5/ES6 继承的几种方法

解:

ES5/ES6 的继承除了写法以外还有什么区别?

解: