javascript高级与面向对象笔记整理,接part4篇!!
词法作用域
词法作用域的概念
变量的作用域在代码写好的时候就已经可以确定,这种作用域就是词法作用域
-
JavaScript
中没有动态作用域 -
JavaScript
中没有块级作用域
变量提升
JS代码执行分两个阶段,首先进行预解析,再执行
在预解析阶段,系统会将所有的变量声明以及函数声明提升到当前作用域的最顶上
- 当函数同名的时候,都会提升,但是后面的函数会将前面的函数覆盖
- 当函数和变量同名的时候,只会提升函数声明,变量声明会被忽略
- 变量提升是分作用域的
- 变量提升是分段(
script
标签) - 函数表达式是不会被提升,提升的只是变量的声明。
var func= function(){};
- 条件式函数声明,根据浏览器不同,提升的情况不同,最新的浏览器中都不会进行提升
作用域链
在 js
中只有函数可以限定作用域,然后,函数中又可以声明函数,这样就形成了一个由内向外进行访问的链式结构,这个结构就叫做作用域链
如何绘制作用域链
- 先画一条直线,表示0级作用域链,也就是全局作用域
- 再在全局作用域中查找变量以及函数的声明,将所有找到的这些成员以小方块的形式放在0级作用域链上
- 如果全局作用域中有函数成员,那就从该函数中在引出一条线,表示1级作用域链
- 再去1级作用域中进行查找变量以及函数的声明,在把他们画出来,
- 如果还有函数,就接着去找。。。。直到没有函数为止
变量的搜索原则
- 首先在当前作用域中进行查找,如果找到了就直接使用
- 如果没有找到,就去上一级作用域中进行查找,如果找到了就直接使用
- 果没有找到,就继续往上查找,直到找到全局作用域为止
如何分析面试题
- 先进行提升处理(把提升后的代码写出来)
- 然后根据作用域及作用域链还有变量搜索原则进行分析
闭包
- 语文解释:封闭的包裹结构
- js的解释:函数就是一个闭包
闭包要解决的问题是什么?
函数内部的数据无法被外界直接访问!
如何解决?
在函数内部返回一个函数,用来操作该函数内部的数据。
闭包的原理(作用域)
函数中的变量无法被上一级作用域访问,但是可以被下一级作用域访问。
闭包的基本模型
1 | function func(){ |
如何访问多个数据?
返回一个对象,对象中包含对所有数据的设置和访问的方法,在函数外部接收到该对象之后,就可以操作函数内部的数据
点击事件的注册问题
如果在for
循环中使用循环的控制变量i来处理点击事件中的内容,那么这个 i
在点击事件触发的时候,循环已经结束,i
已经变成了最后一个值,所以会不准确
如何解决
在点击事件的处理函数内部,访问的时候,不要去使用 i
,而是使用这个函数自己的一个私有的数据。
所以需要使用一个拥有自己的变量的函数来做点击事件的处理函数。
这个函数需要通过闭包来创建。
1 | function f1(j){ |
上面的函数调用之后的返回值,就拥有了自己独立的变量,我们可以使用它来做点击事件的处理函数
setTimeout的回调函数执行时间问题
setTimeout
和 setInterval
中的回调函数,会在所有的主逻辑代码执行完之后,才依次检查执行时间是不是到了,到了就会执行
当把 setTimeout
放在一个for循环语句中的时候,如果在回调函数中使用了循环中变量i
那么,当 setTimeout
的回调函数执行的时候, for
循环已经执行完毕,i已经是最后一个值
解决办法
回调函数不应该去使用 for
循环中的 i
,而是使用自己的一个私有变量
1 | function f(j){ |