问:什么是闭包?
答:
闭包是一个函数及其捆绑的周边环境状态,换言之,闭包让内部函数可以访问外部函数作用域(定义),延伸了变量的作用范围(作用),常用来实现变量/方法私有(使用场景),但闭包在IE9之前版本中可能造成内存泄漏(存在问题),退出函数之前需要将变量赋值null清除(解决方法)
闭包示例代码:
const fn = (()=>{
//定义外部函数的局部变量o
let o = 123
//外部函数返回的这个内部函数就是一个闭包(一个函数及其捆绑的周边环境状态)
return ()=>{
console.log(o++)
}
})()
//引申:私有变量/局部变量/全局变量的区别:全局变量可以在全局环境内访问/修改,局部变量只能在局部作用域内访问/修改,私有变量只能在局部作用域内修改,但可以在不止局部作用域的作用域内访问,私有变量比全局变量安全,比局部变量作用范围广
//变量私有的必要性:比如这里,如果o++不是在闭包中执行,而是在外部函数执行,那么每次调用外部函数,o都会重新初始化,每次都是从123开始,无法实现累加效果
//内部函数访问到了外部函数的作用域,变量o成为了内部函数的私有变量,延伸了变量o的作用范围
fn()//123
fn()//124
fn()//125
//造成的问题:在IE9之前版本中,变量o在外部函数执行完毕之后不会被回收,因为他被内部函数调用了,变量o占用的内存一直得不到释放,造成了内存泄漏,内存泄漏过多,就可能导致内存溢出(内存不够用)
//解决方法:在退出函数之前,执行o=null,将变量o手动清除
问:哪些操作会造成内存泄漏?怎么解决?
答:
<1>对象彼此引用=》解决:避免对象彼此引用
<2>没有设置跳出的无限循环,比如没有清理的间隔函数=》解决:无限循环设置跳出
<3>创建全局变量(全局变量在页面关闭之前不会被回收,尤其避免生成意外的全局变量,即不声明直接对变量赋值)=》解决:在JavaScript文件开头添加use strict,使用严格模式,防止意外的全局变量
问:说说你对原型的理解?
答:原型是一个共享对象(广义)的对象,有两个引用,分别是构造函数的prototype属性和对象的__proto__属性,原型对象与构造函数的this都指向实例对象,通过构造函数的this为实例对象添加复杂数据类型属性,每次实例化都要在堆中占用一块内存,堆中存放了很多重复的数据,如果将复杂数据类型属性放在原型对象中,他们在堆中就只占据一块内存,所有实例对象通过__proto__属性访问原型对象读取他们,构造函数通过prototype属性访问原型对象读写他们
问:介绍下原型链?(解决的是继承问题么)
答:是,当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去他的__proto__隐式原型上查找,即他的构造函数的prototype,如果还没有找到就会再在构造函数的prototype的__proto__上查找,这样一层一层向上查找就会形成一个链式结构,称之为原型链。
图示: