作用域与闭包第一二三章
来源:互联网 发布:pdb数据库 编辑:程序博客网 时间:2024/06/11 10:56
作用域与闭包
第一章:什么是作用域
-在变量中存储值和取出值的能力,给程序赋予了状态
-变量存活在哪里
-程序如何找到它们
-定义规则:作用域
编译器理论
-传统编译型:“编译”
1.分词/词法分析
-token(记号):将一连串字符打断成有意义的片段
2.解析
-将一个token的流(数组)转换为一个嵌套元素的树
-综合表示了程序的语法结构
-抽象语法树(AST—Abstract Syntax Tree)
3.代码生成
-将抽象语法树转换为可执行的代码
-JavaScript
1.JS引擎没有大把时间去优化
2.JS代码段刚好在它之前被编译
理解作用域
-过程处理想象成一场对话
-演员
1.引擎:负责从始至终编译和执行JS程序
2.编译器:解析和代码生成
3.作用域:收集维护被声明变量的列表,制定访问规则
-反复
1.编译期间:声明一个变量(先前没有在当前作用域中声明过)
2.执行期间:在作用域中查询变量并赋值(如果找到的话)
-编译器术语
1.”LHS”查询(Left-hand Side)
-变量出现在赋值操作的左手边 a = 2;
-赋值的目标
2.”RHS”查询(Right-hand Side)
-简单查询变量的值console.log(a);
-赋值的源
嵌套的作用域
-遍历嵌套作用域简单规则
-从当前执行的作用域一直往上级查找,到最外层的全局作用域停止
-错误
1.RHS查询找不到会导致引擎抛出ReferenceError
2.非Strict模式LHS查询没有会在全局作用域中创建同名新变量
3.ReferenceError:作用域解析失败
4.TypeError:作用域解析成功,试图对结果进行非法/不可能动作
第二章:词法作用域
-作用域的工作方式模型
1.词法作用域:常见,绝大多数编程语言使用
2.动态作用域:Bash脚本,Perl中的一些模式
-词法分析时
-词法作用域是在词法分析时被定义的作用域
-将词法作用域看作是仅仅依靠词法的
-查询
1.一旦找到第一个匹配,作用域查询就停止
2.“遮蔽”(shadowing):内部的标识符遮蔽了外部的标识符
3.全局变量 window.a访问
4.词法作用域由这个函数被声明的位置唯一定义
-欺骗词法作用域
1.会导致更低下的性能
2.eval(…):在运行时修改一个编写时的词法作用域
-Strict模式不会实际修改
-setTimeout(),setInterval()可以为它们各自第一个参数值接收一个字符串,其内容会被eval为一个动态生成函数的代码(老旧废弃别做)
3.with:从你传递给它的对象中凭空创造了一个全新的词法作用域
4.性能:存在eval和with将不会做优化,代码运行慢(假定自己知道的所有标识符位置无效)
第三章:函数与块作用域
-函数中的作用域
1.JavaScript拥有基于函数的作用域
2.函数作用域:所有变量属于函数,贯穿整个函数使用/重用/嵌套访问
-隐藏于普通作用域
1.将变量和函数围在一个函数的作用域中来”隐藏”它们
2.最低权限原则(note-least privilege/最低授权/最少曝光):私有细节保持为私有
3.避免冲突:避免同名用处不同的标识符之间发生无意的冲突
4.全局“名称空间”:多个库加载到全局作用域中(为库创建单独的变量声明)
5.模块管理:通过依赖管理器(库导入指定作用域)回避冲突
-函数作为作用域
1.区分函数声明和函数表达式
-名称作为一个标识符被绑定在何处
-外部为声明function foo(){}内部表达式(function foo(){…})()
2.匿名和命名
-函数声明不能省略名称
-匿名缺点:栈轨迹无名称使调试困难/自引用困难/描述性名称帮助自解释
-内联函数表达式:强大有用(最佳方法命名函数表达式)
3.立即调用函数表达式
-IIFE(ImmediatelyInvoked Function Expression):立即被调用的函数表达式
-利用只是函数调用的事实,来传入参数值
var a =2;
(functionIIFE(global ){
var a =3;
console.log( a );// 3
console.log(global.a );// 2
})(window );
console.log( a );// 2
-变种先定义后传值:用于UMD(Universal Module Definition统一模块定义)项目,繁杂
var a =2;
(functionIIFE( def ){
def( window );
})(functiondef( global ){
var a =3;
console.log( a ); // 3
console.log( global.a ); // 2
});
-块儿作为作用域
1.尽量靠近的局部的在变量将被使用的位置声明它
2.bar仅在声明作用域使用 var总属于外围作用域
3.是一种扩展了早先的”最低暴露原则”
4.with块、try/catch的catch块
5.let声明的变量依附所在块(之下),不暴露给外作用域
{
console.log( bar ); // ReferenceError!
let bar =2;
}
6.垃圾回收:关于闭包和释放内存的垃圾回收
-声明可以将变量绑定在本地的明确的块(块作用域)
7.let循环
for (let i=0; i<10; i++) {
console.log( i );
}
console.log( i ); // ReferenceError
8.const创建一个块儿作用域变量,值固定
-总结
应当同时使用函数作用域和块儿作用域技术—在它们各自可以产生更好,更易读/易维护代码的地方。
- 作用域与闭包第一二三章
- 作用域与闭包
- 作用域与闭包
- 作用域与闭包
- 作用域与闭包
- javascript函数作用域与闭包
- 深入浅出闭包与作用域链
- 深入浅出闭包与作用域链
- 作用域链与闭包
- JQuery_JavaScript___闭包与作用域
- Javascript 闭包与作用域
- 闭包与作用域链
- Javascript闭包与作用域
- JavaScript闭包作用域与this
- Javascript中的闭包与作用域
- javascript作用域与闭包
- js作用域与闭包
- JavaScript作用域链与闭包
- 第九次作业
- Java学习之第四课
- 微信小程序生命周期
- Spark基本概念快速入门
- Java初学之HelloWord
- 作用域与闭包第一二三章
- 多文件上传MVC
- Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before
- 淘宝的购物
- 关于c语言中各符号的意义,以及优先级。
- Recycleviewswipe加载刷新
- git版本控制系统命令一
- L18 文本编辑工具Vim(二)
- post请求百度网址内容和访问本地springmvc工程controller