1.构造函数与普通函数 箭头函数的三种区别
1.构造函数的this指向实例化后的那个对象 2.普通函数的this指向调用该函数的那个对象 3.箭头函数的this指向创建时的那个对象,而不是引用时的那个对象
2.什么是闭包
可以打破作用域链的规则
3.什么是作用域链
当前作用域-->父级作用域-->全局作用域 形成的作用域链条
4.什么是内存泄漏
内存泄漏的含义就是当已经不需要某块内存时这块内存还存在着
5.什么是垃圾回收机制
JS的垃圾回收机制是为了以防内存泄漏,内存泄漏的含义就是当已经不需要某块内存时这块内存还存在着,
垃圾回收机制就是间歇的不定期的寻找到不再使用的变量,并释放掉它们所指向的内存。
6.原型
所有的构造函数都有一个prototype属性,这个属性就称为原型对象 所有的构造函数new出来的对象都有一个__proto__ 属性 , 这个属性也对应着一个对象就是原型对象
原型对象上的属性和方法不能直接被子类访问(继承中实现)
Javascript的继承机制基于原型,而不是Class类
7.原型链
实例对象和原型之间的连接 就称为原型链 原型模式的执行流程 : 首先在实例上查找 找到后就返回 再去在构造函数的原型上查找 找到后就返回 继续去 OBject.prototype 上查找 找到后就返回
8.原型链和作用域链的区别
原型链是作用在构造函数上 原型链操作的是构造函数的属性 实例属性 原型属性 作用域链是 作用在普通函数上 作用域链操作的数全局变量或局部变量
9.继承
构造函数继承原理: 调用父类构造函数,并改变其中的this指向
继承方式一:通过改变父类的执行环境 实现继承
function Parent(){ this.money = 99999999999999999; this.sing = function(){ console.log("会唱歌"); } } function Son(){ 在子类中定义一个属性 指向父类的构造函数 this.pre = Parent; 在子类中调用父类 this.pre(); }
继承方式二:使用call或apply继承或bind继承(构造函数继承) 原理 : 在子类中使用call或apply的方式调用父类 让父类中的this指向子类new出来的对象 call和apply的区别 : call的第二个参数个数不固定 apply的第二个参数是一个数组 这个数组可以使用arguments来代替 用法 : 父类.call( this指向 , 继承属性 ) 父类.apply( this指向 , [继承属性] ) bind也可以实现继承 : 父类.bind(this指向)(继承属性) 总结call和apply : 可以执行函数 可以带入参数 可以改变调用函数中this的指向 不能用于创建函数
原型继承(原型链继承) 让子类的原型对象指向父类的实例 子类.prototype = new 父类()
混合继承 混合构造函数继承和原型链继承 使用call或apply方式 继承实例属性 和 实例方法 使用原型继承 继承 原型方法
ES6继承 class Son extends Father{ constructor(name,age,score){ super(name,age);//继承父类的属性和方法 this.score = score;//子类特有的属性 } //子类特有的方法 study(){ return "学习ing"; } } ES6继承中super指向的对象可以是: 父类的构造函数 父类 父类的原型对象 不会指向父类的原型方法
Object.cerate()实现继承 function Father(name,age){ this.money = 9999999; this.dance = function(){ console.log(8) } } var a = new Father(); 创建一个父类对象 var b = Object.create(a); 子类 console.log(b)
10.事件委托
委托:让别人去做 事件委托: 当需要为多个同类的标签添加相同的事件时,可以将这个事件添加到这一批同类标签的父级元素上 事件委托的好处: 减少了事件绑定浏览器重绘的次数,提高了程序的执行效率 减少事件的沉余绑定,节约了事件资源 可以解决动态添加的元素节点无法绑定事件的问题 事件委托机制: 利用事件冒泡或者捕获的机制完成的 不能冒泡的事件也就不能使用事件委托 事件委托两个核心步骤: 获取事件源:e.target || e.srcElement 明确事件源: 可以通过标签名 tagName/nodeName 可以通过 类名 className 可以通过 id 可以通过 自定义属性 getAttribute()
11.事件冒泡
当触发某个事件时,同样的事件会向父元素触发,这种现象就叫做事件冒泡 阻止事件冒泡 : e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true; 不是所有的事件都会产生冒泡现象 ,一般会产生冒泡现象常用事件 : onclick onmouseover onkeyup onkeydown 不会产生冒泡的行为的事件 : onload onfocus onblur
事件原理 : 三个阶段 事件捕获阶段 目标阶段(事件源) 冒泡阶段
12.事件循环机制
JavaScript 事件循环机制分为浏览器和 Node 事件循环机制,两者的实现技术不一样,浏览器 Event Loop 是 HTML 中定义的规范,Node Event Loop 是由 libuv 库实现。这里主要讲的是浏览器部分。 Javascript 有一个 main thread 主线程和 call-stack 调用栈(执行栈),所有的任务都会被放到调用栈等待主线程执行。 JS 调用栈 JS 调用栈是一种后进先出的数据结构。当函数被调用时,会被添加到栈中的顶部,执行完成之后就从栈顶部移出该函数,直到栈内被清空。 同步任务、异步任务 JavaScript 单线程中的任务分为同步任务和异步任务。同步任务会在调用栈中按照顺序排队等待主线程执行,异步任务则会在异步有了结果后将注册的回调函数添加到任务队列(消息队列)中等待主线程空闲的时候,也就是栈内被清空的时候,被读取到栈中等待主线程执行。任务队列是先进先出的数据结构。 Event Loop 调用栈中的同步任务都执行完毕,栈内被清空了,就代表主线程空闲了,这个时候就会去任务队列中按照顺序读取一个任务放入到栈中执行。每次栈内被清空,都会去读取任务队列有没有任务,有就读取执行,一直循环读取-执行的操作,就形成了事件循环。
定时器 定时器会开启一条定时器触发线程来触发计时,定时器会在等待了指定的时间后将事件放入到任务队列中等待读取到主线程执行。 定时器指定的延时毫秒数其实并不准确,因为定时器只是在到了指定的时间时将事件放入到任务队列中,必须要等到同步的任务和现有的任务队列中的事件全部执行完成之后,才会去读取定时器的事件到主线程执行,中间可能会存在耗时比较久的任务,那么就不可能保证在指定的时间执行。 宏任务(macro-task)、微任务(micro-task) 除了广义的同步任务和异步任务,JavaScript 单线程中的任务可以细分为宏任务和微任务。 macro-task包括:script(整体代码), setTimeout, setInterval, setImmediate, I/O, UI rendering。 micro-task包括:process.nextTick, Promises, Object.observe, MutationObserver。
13.浏览器渲染页面的流程
(1)解析HTML文件,构建 DOM Tree (2)解析CSS,构建 CSSOM Tree(CSS规则树) (3)将 DOM Tree 和 CSSOM Tree合并,构建Render tree(渲染树) (4)reflow(重排):根据Render tree进行节点信息计算(Layout) (5)repaint(重绘):根据计算好的信息绘制整个页面(Painting)
14.ES6
Generator函数 const:定义常量的关键字 常量一旦被定义,值就不会发生变化(值不可以被改变) let:定义变量的关键字 块级作用域 this 表示当前对象 解构赋值:包括字符串的解构赋值 对象的解构赋值 数组的解构赋值 函数参数的解构赋值 for..of : 遍历数组 字符串模板:`` 使用${变量或函数调用} 箭头函数:箭头函数没有this指向 Array.from:将一个具有length长度的书香的伪数组转为真正的数组 Array.of(): 方法用于将一组值,转换为数组 Object.assign():方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将 返回目标对象 set集合: 自动去重 数据不会进行类型转换 Array.from( new Set( arr ) ) 数组去重 史上最短的数组去重方案 : [... new Set( arr )] set集合操作方法 : add() 向集合中添加一个数 delete() 删除集合中的一个数 has() 判断集合中是否含有某个数 clear() 清空集合 map集合 map的操作方法 : set() 为map集合赋值 get() 根据键 获取值 delete() 删除数据 has() 判断是否含有某个键 clear() 清空 Symbol类型: 可以将一个Symbol类型的变量作为对象的属性,对对象的属性起到保护作用 使用 for in 遍历这个对象时,取不到Symbol类型的属性 构造函数 class--类 instanceof 判断创建的对象属于哪一个构造函数 class 构造函数名{ }