一、声明提升
1.变量声明提升
使用var声明的变量,会被提升到当前作用域的最顶端先赋值一个undefined的值。总的来说,就是先被声明(赋值一个undefined),实际的赋值操作留在原地执行。
![](https://img.haomeiwen.com/i8054470/dbd3a9200f41cfe4.png)
![](https://img.haomeiwen.com/i8054470/4fddce895b4e6d2b.png)
那么当前作用域和顶层作用域都生命了同一变量,就近原则,距离最近的变量优先,每个var都会将变量声明提前。只有在全局声明的变量,会被复制到window对象上一份。
2.函数声明提升
函数的种类:声明式函数、赋值型函数、匿名函数、自执行函数
声明式函数
![](https://img.haomeiwen.com/i8054470/98d4679c4376e161.png)
赋值型函数
![](https://img.haomeiwen.com/i8054470/0448d91547e80c2b.png)
JS解析分为两个阶段:预编译和执行。
预编译:对当前js文件中所有的声明变量和函数进行处理,此时处理的只有【声明式函数】直接声明并且赋值,变量也只是进行声明,并未初始化和赋值。
重点: 1. 都是函数声明的情况下,下面会覆盖上面的函数
![](https://img.haomeiwen.com/i8054470/e4f3f01d9981bbf2.png)
2. 执行在最前,声明函数 > 赋值函数
![](https://img.haomeiwen.com/i8054470/f9c2ab06a422dfce.png)
执行在最后,那么赋值型函数 > 声明式函数
![](https://img.haomeiwen.com/i8054470/d7f7006bbb6ef63e.png)
3. js加载代码块是按照顺序的,如果【声明所在】的文件在【调用所在】的文件下面,那么调用会报错。
4.函数声明 > 变量声明,会优先把标识符给函数用。
3.变量提升VS函数
声明提升的顺序,是先var后function
![](https://img.haomeiwen.com/i8054470/42fa1fe8dddc04a3.png)
![](https://img.haomeiwen.com/i8054470/b09282bf52a04051.png)
二、JS作用域
1.局部作用域
局部变量和参数重名时,同等优先级,默认访问当前位置之前最近的值。
2.全局作用域
js文件内的任何地方直接对变量赋值,不适用var声明的变量,默认为全局变量。
var a = b = 10; => b = 10; var a = b;就是默认b为全局变量,a为局部变量
三、经典面试题
![](https://img.haomeiwen.com/i8054470/2f9d633831c3d31c.png)
四、移动端H5点击穿透
pc端的点击事件: mousedown -> click -> mouseup
h5的点击事件:手机上无鼠标,所以使用touch代替:touchstart -> touchmove -> touchend -> tap -> click 。
touchend结束后,会延迟300ms左右出发click事件。这是因为手机上有双击事件,如果300ms内发生了第二次click,就会直接出发dbclick,而不是click事件了。所有click 、dbclick都是在点击300ms之后又进行确认触发的。
那么点击穿透的意思就是:在弹层的关闭按钮触发【touchend / tap】事件之后,弹层立即关闭,但是300ms后,下面的元素会触发自己的click事件。
解决办法: 1. 遮挡,确保300ms左右,弹层没有完全消失。例如zepto的fadeOut,动画时间是300ms。
2. css3,pointer-events: none;元素不再是鼠标事件的目标,就是click事件不会触发了。意思就是在触发【touchend / tap】事件时,下面的元素pointer-events置成none,300ms之后再改回auto;
五、改变this的指向
this的指向只有在被调用的时候才能确定。永远指向最后被【调用】的对象
1. 单层
相当于被window调用的,this指向window;
![](https://img.haomeiwen.com/i8054470/b12a08a7d672e66f.png)
2.多层
this指向最近的上1层对象
![](https://img.haomeiwen.com/i8054470/c0becf494d930367.png)
3. this撞上return
如果return的是一个对象,那么this就指向那个对象,return其他的,this还是指向函数实例。null特殊,也会指向函数实例。
4. 改变this的指向
4.1 new一个对象实例,this指向该实例
4.2 call
4.3 apply
4.4 bind
六、AJAX的请求步骤
1. 创建XMLHttpRequest对象
![](https://img.haomeiwen.com/i8054470/c0a951ecef629fae.png)
2.创建HTTP请求
配置HTTP请求参数
![](https://img.haomeiwen.com/i8054470/d106c6ffa22c43ca.png)
3.配置响应回调
在发送之前,最好先配置一下http请求之后的回调函数。
http请求的状态变化会触发onreadystatechange事件,判断XMLHttpRequest.readyState的状态,等于4 的时候,数据接收完成。
4.获取返回的数据
![](https://img.haomeiwen.com/i8054470/30db9efee5eba22d.png)
5.发送请求
![](https://img.haomeiwen.com/i8054470/5bc309b8f65ae64c.png)
网友评论