原型和原型链
- 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 的继承除了写法以外还有什么区别?
解: