for in 和 for of 的区别
for in 是 es5 的标准,用来遍历的是 key,仅适用于数组。
for of 是 es6 的标准,用力遍历可迭代对象的 value。
js 的数据类型
null、undefined、boolean、object、number、string、BigInt、Symbol。
typeof 返回值
用于判断数据类型,返回值主要有 string、boolean、number、function、object、undefined
instanceof
instanceof 判断该对象是谁的实例。instanceof 检测一个对象 A 是不是另一个对象 B 的实例的原理是:查看对象 B 的 prototype 指向的对象是否在对象 A 的[[prototype]]链
上。如果在,则返回 true,如果不在则返回 false
闭包
闭包是有权访问另一个函数作用域的变量的函数。
当函数可以记住并访问所在的词法作用域时,就产生了闭包。
闭包用途
- 能够访问函数定义时所在的词法作用域。
- 私有化变量。
- 模拟块级作用域
- 创建模块。
缺点:内存泄漏,不释放。
原型和原型链
原型:对象固有proto属性,该属性指向对象的 prototype 属性。
原型链:当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会从它的原型对象上去找这个属性,层层向上,终点是Object.prototype
。
this 指向、new 关键字
this 对象是执行上下文中的一个概念,它指向最后一次调用这个方法的对象。
- 在全局函数中,this 指向 window。
- 当函数作为某个对象调用时,指向该对象。
- 构造函数调用,this 指向该构造函数。
- 通过 bind、apply、call 调用。修改了指向。
- 箭头函数中的 this 指向的是定义时 this 的指向。它会捕获其所在(即定义的位置)上下文的 this 值, 作为自己的 this 值,
- dom 事件处理函数中的 this,addEventListener,指向 dom 元素。
作用域、作用域链、变量提升。
作用域负责收集和维护所有声明的标识符(变量)组成的一系列查询,用于确定当前执行的代码对这些标识符的访问权限。
目前分为全局作用域、函数作用域、块级作用域。
作用域链是从当前作用域一层层向上寻找某个变量,直到全局作用域中。
继承的方式
首先定义一个父类:
// 定义一个动物类
function Animal(name) {
// 属性
this.name = name || "Animal";
// 实例方法
this.sleep = function () {
console.log(this.name + "正在睡觉!");
};
}
// 原型方法
Animal.prototype.eat = function (food) {
console.log(this.name + "正在吃:" + food);
};
- 原型链继承
将父类的实例作为子类的原型
function Cat() {}
Cat.prototype = new Animal();
Cat.prototype.name = "cat";
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.eat("fish"));
console.log(cat.sleep());
console.log(cat instanceof Animal); //true
console.log(cat instanceof Cat); //true
- 构造继承
使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)
function Cat(name) {
Animal.call(this);
this.name = name || "Tom";
}
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true
剩下的可看这个https://www.cnblogs.com/humin/p/4556820.html,用的较少,不做深入了解了。
EventLoop
JS 单线程,,异步队列又分为宏任务队列和微任务队列,因为宏任务队列的执行时间较长,所以微任务队列要优先于宏任务队列。微任务队列的代表就是,Promise.then,MutationObserver,宏任务的话就是 setImmediate setTimeout setInterval。
事件冒泡机制
事件冒泡指在在一个对象上触发某类事件,如果此对象绑定了事件,就会触发事件,如果没有,就会向这个对象的父级对象传播,最终父级对象触发了事件。
事件委托本质上是利用了浏览器事件冒泡的机制。因为事件在冒泡过程中会上传到父节点,并且父节点可以通过事件对象获取到目标节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件,这种方式称为事件代理。
实现双向绑定 Proxy 与 Object.defineProperty 相比优劣如何?
- Object.definedProperty 的作用是劫持一个对象的属性,劫持属性的 getter 和 setter 方法,在对象的属性发生变化时进行特定的操作。而 Proxy 劫持的是整个对象。
- Proxy 会返回一个代理对象,我们只需要操作新对象即可,而 Object.defineProperty 只能遍历对象属性直接修改
- Object.definedProperty 不支持数组,更准确的说是不支持数组的各种 API,因为如果仅仅考虑 arry[i] = value 这种情况,是可以劫持 的,但是这种劫持意义不大。而 Proxy 可以支持数组的各种 API。