作用域&闭包

题目(答案见每题下方空白处)

  1.说一下对变量提升的理解

  变量提升即JS的预解析,也就是var声明的变量以及function开头的函数声明会在预解析时被提到整段代码的最前面,变量赋值为undefined,函数则直接为本体

  而函数中的预解析还包括arguments(形参)和this指向,arguments也会被初始化赋值为undefined

  2.说明this几种不同的使用场景

  构造函数、对象属性、普通函数、call/apply/bind

  3.创建10个a标签,点击每一个弹出对应的序号

  (用闭包/let写)

  4.如何理解作用域

  (关键点:自由变量、作用域链、闭包的两个场景)

  5.实际开发中闭包的使用

  闭包可以用来收敛权限

 

知识点

执行上下文(预解析)

  执行上下文(预解析)针对一段script/一个函数

  全局中,提前拿出变量定义和函数声明,给变量初始化为undefined,函数则直接把函数本体丢到最前面

  函数中提前拿出变量定义、函数声明、this和arguments,同样给变量初始化为undefined,函数也直接把本体丢到最前面去,this和arguments在函数执行前也都确定了值

this

  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

十个li标签的弹出问题

  1.可以用闭包(自执行匿名函数)解决

  

  2.可以用let的块级作用域特性解决

  

实际开发中的应用

  闭包的特点在于,可以访问到函数作用域内部的局部变量,而局部变量是无法在外部修改的(除非提供API)

  因此可以利用这一特性,限制权限

  

  这里的list是函数的局部变量,不可以被修改,而函数只能用来记录某个数据是否出现过

posted @ 2019-09-22 22:12  且听风吟720  阅读(111)  评论(0编辑  收藏  举报