读书笔记-you-don't-konw-js
第一部分:作用域和闭包
不要满足于只是让代码正常工作,而是弄清楚为什么是这样
作用域是什么
定义的变量存储在哪里?程序是如何找到变量的?实现的 规则就是作用域
传统编译语言执行前的编译三步骤(p5)
- 分词/ 词法分析(Tokenizing/ Lexing)
- 解析/ 语法分析 (Parsing)
- 代码生成
理解作用域
- 引擎--负责编译与执行整个过程
- 编译器 -- 语法分析与代码生成等
- 作用域 -- 收集并维护声明的变量查询,确定标识符的访问权限
LHS和RHS
含义是赋值操作的左侧或者右侧,并不一定是“=赋值操作符的左侧或者右侧”,因此在概念上可以理解为“赋值的对象是谁(LHS)”和“谁是赋值操作的源头(取源RHS)”
// 练习
// 请问引擎和作用域通话,分别进行了多少次LHS和RHS查询
// 请指出
function foo (a) {
var b = a;
return a + b;
}
var c = foo(2);
3处LHS查询是
me:
1:foo(..)赋值给c;
2:隐式将2 赋值给 a;
3:a赋值给b;
参考:
c = ..、 a = 2(隐式变量分配)、b = ..
4处RHS查询是
me:
1:引擎通过作用域知道c是一个foo
2:引擎通过作用域知道foo是个函数
3:?
4:return
参考:
foo(2..、 = a、 a..、 ..b(return 处的a 与 b 分别进行了一次RHS)
作用域嵌套
一个块或者函数嵌套在另一个块或者函数中就发生了作用域的嵌套。
嵌套作用域中的查询规则:“就近原则”,当前作用域中没有找到目标,则沿着原型链往外一层一层找,直到全局作用域。在全局作用域中未找到,查找停止,抛出异常。
区分LHS和RHS的重要性:变量未声明时,两种查询的行为不一样。
function foo (a) {
console.log(a + b);
b = a;
}
第一次在对b进行RHS查询时找不到该变量,引擎抛出ReferenceError错误;相较之下LHS查询在到不到时, “非严格模式”下会隐式创建全局变量,比如 b = a
;
- ReferenceError 同作用域判别失败相关, 而 TypeError 则代表作用域判别成功了, 但是对结果的操作是非法或不合理的
词法作用域
略
函数作用域和块作用域
函数作用域的含义是指,属于这个函数的全部变量都可以在整个函数的范围内使用及复用。
我们都知道JS具有基于函数的作用域,(ES6出现了块级作用域)在函数内声明的变量和嵌套的函数都可以在函数内调用,外部不允许访问(符合最小特权原则)。这样设计的好处是能充分利用JavaScript 变量可以根据需要改变值类型的“ 动态” 特性。与此同时,还要避免隐式全局变量的声明。
规避冲突
全局命名空间
模块管理 (p26)
函数声明和函数表达式
两者之前最重要的区别是他们的名称标识符将会绑定在何处。
补充: 名称标识符
立即执行函数表达式IIFE( Immediately Invoked Function Expression)p28
块作用域
- with语句会创建
- try/catch 语句中catch分句会创建
- let关键字
- const关键字
提升是指声明会被视为存在于其所出现的作用域的整个范围内。
let声明的变量不会提升
{
console.log( bar ); // ReferenceError!
let bar = 2;
}
显示声明块级作用域
// 使用{ } 显示声明let
{
let a = 0;
console.log(a);
}
const定义个一个块常量,定义之后不允许改变。
块作用域与垃圾回收
function process(data) {
// 在这里做点有趣的事情
}
// 1.内存可能没有释放
var someReallyBigData = { .. };
process( someReallyBigData );
// 2.在这个块中定义的内容可以销毁了!
//{
// let someReallyBigData = { .. };
// process( someReallyBigData );
// }
var btn = document.getElementById( "my_button" );
btn.addEventListener( "click", function click(evt) {
console.log("button clicked");
}, /*capturingPhase=*/false );
由于 click 函数形成了一个覆盖整个作用域的闭包, JavaScript 引擎极有可能依然保存着someReallyBigData ( 取决于具体实现)。但是2. 声明了块作用域,引擎明确知道click函数不需要someReallyBigData ,使someReallyBigData 得内存占用得到释放。
为变量显式声明块作用域, 并对变量进行本地绑定是非常有用的工具
提升
概念:代码在执行前,声明(函数和变量)会都会在其作用域的顶端,可看做声明的变量或者函数移动到了作用域的最顶端。
// 举例:
{
console.log(a) // undefined
var a = 1
}
引擎在执行前词法分析一步将上面代码看做 var a 声明和 a = 1 赋值两步,声明var a 将会被提升,因此在执行性console.log(a) 时, 引擎已经知道a,由于赋值保留在代码赋值的位置,所以a为undefined。如果a没有提升,浏览器将会报ReferenceError 错误。
注意:
函数表达式不会提升。
函数优先
foo() // foo
var foo;
function foo () {
console.log('foo')
}
尽管 var foo定义在function foo ... 之前, 但由于function foo .. 函数声明优于变量声明, var foo 重复声明被忽略,因此 foo() 能够正确执行。如果var foo 变量在function foo 之前声明, 那么函数foo将作为重复声明而被忽略, 导致foo()执行包ReferenceError错误。
作用域闭包
读书笔记-you-don't-konw-js的更多相关文章
- 【js】【读书笔记】廖雪峰的js教程读书笔记
最近在看廖雪峰的js教程,重温了下js基础,记下一些笔记,好记性不如烂笔头嘛 编写代码尽量使用严格模式 use strict JavaScript引擎是一个事件驱动的执行引擎,代码总是以单线程执行 执 ...
- 【第三周读书笔记】浅谈node.js中的异步回调和用js-xlsx操作Excel表格
在初步学习了node.js之后,我发现他的时序问题我一直都很模糊不清,所以我专门学习了一下这一块. 首先我们来形象地理解一下进程和线程: 进程:CPU执行任务的模块.线程:模块中的最小单元. 例如:c ...
- 《javascript权威指南》读书笔记——第二篇
<javascript权威指南>读书笔记——第二篇 金刚 javascript js javascript权威指南 今天是今年的196天,分享今天的读书笔记. 第2章 词法结构 2.1 字 ...
- 《javascript权威指南》读书笔记——第一篇
<javascript权威指南>读书笔记——第一篇 金刚 javascript js javascript权威指南 由于最近想系统学习下javascript,所以开始在kindle上看这本 ...
- js读书笔记
js读书笔记 基本类型的基本函数总结 1. Boolean() 数据类型 转换为true的值 转换为false的值 Boolean true false String 任何非空字符串 "&q ...
- Node.js高级编程读书笔记Outline
Motivation 世俗一把,看看前端的JavaScript究竟能做什么. 顺便检验一下自己的学习能力. Audience 想看偏后台的Java程序员关于前端JavaScript的认识的职业前端工程 ...
- JavaScript、jQuery、HTML5、Node.js实例大全-读书笔记3
技术很多,例子很多,只好慢慢学,慢慢实践!!现在学的这本书是[JavaScript实战----JavaScript.jQuery.HTML5.Node.js实例大全] JavaScript.jQuer ...
- JavaScript、jQuery、HTML5、Node.js实例大全-读书笔记2
技术很多,例子很多,只好慢慢学,慢慢实践!!现在学的这本书是[JavaScript实战----JavaScript.jQuery.HTML5.Node.js实例大全] JavaScript.jQuer ...
- 读书笔记 - js高级程序设计 - 第十五章 使用Canvas绘图
读书笔记 - js高级程序设计 - 第十三章 事件 canvas 具备绘图能力的2D上下文 及文本API 很多浏览器对WebGL的3D上下文支持还不够好 有时候即使浏览器支持,操作系统如果缺缺 ...
- 读书笔记_MVC__关于通过js构建ORM,实现Model层
最近一直在学习MVC构建富应用的WEB程序,自己一直对MVC的设计模式理解的不是十分透彻,终于在研读了github上Spine的源码之后,对构建Model层有了一点自己的理解. 本文仅为个人理解,如有 ...
随机推荐
- 从零开始山寨Caffe·陆:IO系统(一)
你说你学过操作系统这门课?写个无Bug的生产者和消费者模型试试! ——你真的学好了操作系统这门课嘛? 在第壹章,展示过这样图: 其中,左半部分构成了新版Caffe最恼人.最庞大的IO系统. 也是历来最 ...
- Oracle OEM
一.OEM是什么 Oracle Enterprise Manager(Oracle企业治理器,简称OEM)是通过一组Oracle程序,为治理分布式环境提供了治理服务. 二.配置OEM 三.启动OEM ...
- 网页制作中在头部固定悬浮table表头(thead)的方法
这两天接了一个需求,页面是这样的 然后需求是页面中的这个表格当页面向上滚动,且表格的表头到达窗口上方时,表头悬浮在页面的上方,表格正常滚动,这样表格内的数据可以随时看到表头内容. 一开始我认为这是极简 ...
- 纯css来实现提示框
用js用多了,就疏忽了最基本的css了---用title属性来实现提示框.下面言归正传------如何用css实现提示框: 1.利用title属性来实现鼠标滑过某个元素时,实现提示整段内容的功能(利用 ...
- Android 怎么退出整个应用程序?
方法一: 我们在写android应用程序时,经常会遇到想退出当前Acitivity,或者直接退出应用程序.我之前的一般操作是按返回键,或者直接按home键直接返回,其实这两种操作都没有关闭当前应用程序 ...
- Django后台
django的后台我们只要加少些代码,就可以实现强大的功能. 与后台相关文件:每个app中的 admin.py 文件与后台相关. 下面示例是做一个后台添加博客文章的例子: 一,新建一个 名称为 zqx ...
- 解决Unity5+Vuforia+Network本地联机发布到Android上白屏的问题
Unity5+Vuforia+Network本地联机,在Android下点击联机,然后识别模型就出现白屏,点击屏幕上相应位置的按钮(已白屏,但点击该看不见的按钮)还是能起作用,如跳转到其他场景正常. ...
- 计数排序和桶排序(Java实现)
目录 比较和非比较的区别 计数排序 计数排序适用数据范围 过程分析 桶排序 网络流传桶排序算法勘误 桶排序适用数据范围 过程分析 比较和非比较的区别 常见的快速排序.归并排序.堆排序.冒泡排序等属于比 ...
- Node.js 框架
Node.js的是一个JavaScript平台,它允许你建立大型的Web应用程序. Node.js的框架平台使用JavaScript作为它的脚本语言来构建可伸缩的应用. 当涉及到Web应用程序的开发 ...
- Linux系统的理解及学习Linux内核的心得
作业列表 (点击作业跳转) linux内核分析作业:以一简单C程序为例,分析汇编代码理解计算机如何工作 linux内核分析作业:操作系统是如何工作的进行:完成一个简单的时间片轮转多道程序内核 ...