目录
栈练习:
一 变量提升和函数提升优先级问题
以上程序报错原因:函数提升优先级高于变量提升且不会被同名变量声明时援盖。但是会被变量赋值后覆盖。
二 作用域和执行上下文区别与联系
作用域分类:
全局作用域
函数作用域
没有块作用域(ES6有了)
作用:隔离变量,不同作用域下同名变量不会有冲突。
区别:
1)全局作用域之外,每个函数都会创建自己的作用域,作用域在函数定义时就已经确定了。而不是在函数调用时
全局执行上下文环境是在全局作用域确定之后,js代码马上执行之前创建,函数执行上下文是在调用函数时,函数体代码执行之前创建
2) 作用域是静态的,只要函数定义好了就一直存在,且不会再变化。执行上下文是动态的,调用函数时创建,函数调用结束时就会自动释放联系
联系:
上下文环境(对象)是从属于所在的作用域:
全局上下文环境==>全局作用域
函数上下文环境==>对应的函数使用域
三 闭包
如何产生闭包?
当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时,就产生了闭包
闭包到底是什么?
使用chrome调试查看
理解一:闭包是嵌套的内部函数
理解二:包含被引用变量(函数)的对象
注意:闭包存在于嵌套的内部函数中
产生闭包的条件:
1)函数嵌套
2)内部函数引用了外部函教的数据(变量/函教)
常见的闭包
(1)将函数作为另一个函数的返回值
(2)将函数作为实参传递给另一个函数调用
闭包作用
(1)使用函数内部的变量在函数执行完后,仍然存活在内存中(延长了局部变量的生命周期)
(2)让函数外部可以操作(读写)到函数内部的数据(变量/函数)
函数执行完后,函数内部声明的局部变量一般是不存在,存在于闭中的变量才可能存在.。在函数外部不能直接访问函数内部的局部变量,但我们可以通过闭包让外部操作它
闭包生命周期
产生:在嵌套内部函数定义执行完时就产生了(不是在调用)
死亡:在嵌套的内部函数成为垃圾对象时
闭包的应用
定义JS模块(具有特定功能的js文件)
将所有的数据和功能都封装在一个函数内部(私有的)
只向外暴露一个包信n个方法的对象或函数
模块的使用者,只需要通过模块暴露的对象调用方法来实现对应的功能
方式一:先创建一个html页面
创建mk.js页面
方式二:
myMk2.js页面:
闭包缺点及解决办法
(1) 内存溢出
一种程序运行出现的错误
当程序运行需要的内存超过了剩余的内存时,就出抛出内存溢出的错误
(2)内存泄露
占用的内存没有及时释放一内存泄露积累多了就容易导致内存溢出
常见的内存泄露::
意外的全局变量
没有及时清理的计时器或回调函数
闭包
闭包面试题
四 对象创建模式
方式一:object构造函数模式
套路:先创建空object对象,再动态添加属性/方法
适用场景:起始时不确定对象内部数据
问题:语句太多
方式二:对象字面量模式
套路:使用{}创建对象,同时指定属性/方法
适用场景:起始时对象内部数据是确定的
问题:如果创建多个对象,有重复代码
方式三:工厂模式
套路:通过工厂函数动态创建对象并返回
适用场景:需要创建多个对象
问题:对象没有一个具体的类型,都是object类型
方式四:自定义构造函数模式
套路:自定义构造函数,通过new创建对象
适用场景:需要创建多个类型确定的对象
问题:每个对象都有相同的数据,浪费内存
方式五:构造函数+原型的组合模式
套路:自定义构造函数,属性在函数中初始化,方法添加到原型上
适用场景:需要创建多个类型确定的对象