1.说一下对变量提高的理解闭包
变量提高即JS的预解析,也就是var声明的变量以及function开头的函数声明会在预解析时被提到整段代码的最前面,变量赋值为undefined,函数则直接为本体app
而函数中的预解析还包括arguments(形参)和this指向,arguments也会被初始化赋值为undefined函数
2.说明this几种不一样的使用场景this
构造函数、对象属性、普通函数、call/apply/bindspa
3.建立10个a标签,点击每个弹出对应的序号对象
(用闭包/let写)blog
4.如何理解做用域ip
(关键点:自由变量、做用域链、闭包的两个场景)作用域
5.实际开发中闭包的使用开发
闭包能够用来收敛权限
执行上下文(预解析)针对一段script/一个函数
全局中,提早拿出变量定义和函数声明,给变量初始化为undefined,函数则直接把函数本体丢到最前面
函数中提早拿出变量定义、函数声明、this和arguments,一样给变量初始化为undefined,函数也直接把本体丢到最前面去,this和arguments在函数执行前也都肯定了值
this只有在执行时才能确认值,而定义的时候没法确认
this可使用在构造函数、对象属性、普通函数、call、apply、bind方法中
构造函数中的this,当实例化一个对象时,构造函数中的this指向这个构造函数自己,而若是直接调用构造函数,则this指向window
对象的属性中,this指向该对象
普通函数中,this指向当前环境(window)
call、apply和bind方法中,this指向第一个传入的参数
两个最基础的点
1.JS中没有块级做用域(ES6的let和const添加了块级做用域)
2.只有全局做用域和函数做用域
ES6中新增的一个特性,对let和const声明的变量,只在其声明的块级做用域中生效
例以下方的两个for语句,var声明的会在循环结束后仍能够访问循环体中的变量,而let声明的则不能够访问
在当前做用域未定义的变量称之为自由变量
对于函数体内部的变量,若是在其函数做用域中未定义,则会往其父级做用域查找是否有定义,有则调用,不然继续往上,直至全级做用域
闭包是用来访问函数做用域中的局部变量的
具体使用场景有二:
1.函数做为返回值
这里返回100是由于f1返回的匿名函数定义的位置在f1中,而f1中的a的值为100,外部的a是全局做用域的,跟匿名函数无关
2.函数做为参数传递
这里返回100是由于f1中的匿名函数定义在f1里,能访问到的是其定义时所处环境的a,因此为100
1.能够用闭包(自执行匿名函数)解决
2.能够用let的块级做用域特性解决
闭包的特色在于,能够访问到函数做用域内部的局部变量,而局部变量是没法在外部修改的(除非提供API)
所以能够利用这一特性,限制权限
这里的list是函数的局部变量,不能够被修改,而函数只能用来记录某个数据是否出现过