说说你对闭包的理解?闭包使用场景
闭包产生的原因
Js 最大的缺点就是没有类,尤其是es5,自身没有面向对象,变量和函数通常都是写在同一个空间中,变量重名—污染,函数名重名—污染 而闭包能够形成一个封闭的空间,可以避免污染,储存私有变量,存在函数里面 ,这个私有变量不会在函数运行完后被清理 ,可以像全局变量一样被使用,不会失效
什么是闭包
官方解释:当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行
词法作用域是作用域的一种工作模型 嵌套函数被返回在外部执行,他的那么它会保留父级函数作用域链不被销毁(函数套函数) 在全局中必须接收返回函数作为变量储存;
优点
- 内容更封闭,保证命名不会冲突;
- 模块化开发—封闭的模块化环境
缺点
闭包最大缺点就是会造成内存泄漏,存在堆中,不会被垃圾回收;
使用场景
- 创建私有变量/延长变量的生命周期
- 柯里化函数(柯里化的目的在于避免频繁调用具有相同参数函数的同时,又能够轻松的重用)
- 模拟私有方法(例如计数器、延迟调用、回调等闭包的应用,其核心思想还是创建私有变量和延长变量的生命周期)
JavaScript原型,原型链 ? 有什么特点?
原型对象
- 每一个函数都有一个原型(prototype)属性,这个属性是一个指针,指向一个对象
- prototype就是通过调用构造函数而创建的那个对象实例的原型对象
- 带来的好处:所有的对象实例共享原型所包含的属性和方法
原型链
- 当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的__proto__(即它的构造函数的prototype)中寻找,没有则继续往上找,一直往上找,会形成一个链式结构,叫做“原型链”,原型链的终点就是null
- 主要思想就是利用原型让一个引用类型继承另一个引用类型的对象和方法
- js的继承主要就是通过原型链实现的
总结
- 一切对象都是继承自Object对象,Object 对象直接继承根源对象null
- 一切的函数对象(包括 Object 对象),都是继承自 Function 对象
- Object 对象直接继承自 Function 对象
- Function对象的__proto__会指向自己的原型对象,最终还是继承自Object对象
Javascript如何实现继承?
原型链继承
涉及的构造函数、原型和实例,三者之间存在着一定的关系,即每一个构造函数都有一个原型对象,原型对象又包含一个指向构造函数的指针,而实例则包含一个原型对象的指针
构造函数继承(借助 call)
相比第一种原型链继承方式,父类的引用属性不会被共享,优化了第一种继承方式的弊端,但是只能继承父类的实例属性和方法,不能继承原型属性或者方法
组合继承
原型链继承 构造函数继承
原型式继承
- 借助Object.create方法实现普通对象的继承
- 实现的是浅拷贝,多个实例的引用类型属性指向相同的内存,存在篡改的可能
寄生式继承
在上面继承基础上进行优化,利用这个浅拷贝的能力再进行增强,添加一些方法
寄生组合式继承
- 寄生组合式继承,借助解决普通对象的继承问题的Object.create 方法,在前面几种继承方式的优缺点基础上进行改造,这也是所有继承方式里面相对最优的继承方式
- es6 class中的extend使用的就是类似寄生组合式的方法
说说JavaScript中的事件模型
事件
在HTML文档或者浏览器中发生的一种交互操作,使得网页具备互动性, 常见的有加载事件、鼠标事件、自定义事件等
事件流经历三个阶段
- 事件
捕获
阶段(capture phase)- 事件捕获与事件冒泡相反,事件最开始由不太具体的节点最早接受事件, 而最具体的节点(触发节点)最后接受事件
- 处于
目标
阶段(target phase) - 事件
冒泡
阶段(bubbling phase)- 事件冒泡是一种从下往上的传播方式,由最具体的元素(触发节点)然后逐渐向上传播到最不具体的那个节点,也就是DOM中最高层的父节点
事件模型分为三种
- 原始事件模型(DOM0级)
- 绑定速度快
- DOM0级事件具有很好的跨浏览器优势,会以最快的速度绑定,但由于绑定速度太快,可能页面还未完全加载出来,以至于事件可能无法正常运行 只支持冒泡,不支持捕获
- 同一个类型的事件只能绑定一次
- 标准事件模型(DOM2级)
- 三个过程:
- 事件捕获阶段:事件从document一直向下传播到目标元素, 依次检查经过的节点是否绑定了事件监听函数,如果有则执行
- 事件处理阶段:事件到达目标元素, 触发目标元素的监听函数
- 事件冒泡阶段:事件从目标元素冒泡到document, 依次检查经过的节点是否绑定了事件监听函数,如果有则执行
- 三个过程:
- IE事件模型(基本不用)
解释下什么是事件代理?应用场景?
事件代理,俗地来讲,就是把一个元素响应事件(click、keydown......)的函数委托到另一个元素,事件委托就是在冒泡阶段完成。
事件委托,会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,而不是目标元素。
当事件响应到目标元素上时,会通过事件冒泡机制从而触发它的外层元素的绑定事件上,然后在外层元素上去执行函数
优点
- 减少整个页面所需的内存,提升整体性能