你不知道的javascript[上]学习总结(第一部分1-3章)
第一部分 作用域和闭包(1-3章)
代码在执行前,会经过三个步骤
分词-词法分析
- 将由字符组成的【代码字串】分解为【有意义的代码块】,被称为【词法单元】
- 比如,var a = 2; 通常会被分解为几个词法单元:var、a、=、2。被称为【词法单元流数组】
解析-语法分析
- 将词法单元流数组转换为一套代表了程序语法的【抽象语法树AST】,数组中的每一项被转化为了AST树中的节点
代码生成
- 将AST转化为一组【机器指令】,用来创建一个叫 a 的变量(内存分配),并将值 2 存储在 a 中
相比较,js引擎更加复杂,会在三个阶段中进行【运行性能优化】,包括【冗余元素优化】
在js中,多数编译发生在【代码执行前几微秒】
作用域是根据名称查找变量的规则
- 引擎,负责整个 js 程序的编译和执行过程
- 编译器,负责语法分析和代码生成
- 作用域,是一套规则,收集维护由所有声明的标识符组成的查询,并确定当前执行的代码是否有权限访问
变量的赋值
- 首先,编译器会询问当前作用域是否存在该变量,如果没有就声明一个
- 然后,在运行时引擎会在作用域中查询该变量,如果有就赋值
- 仍以 a=2 为例,引擎会为变量 a 进行【LHS查询(左查)】
- LHS查询会试图找到变量 a 的容器本身,并对其赋值。另一种【LHR查询(右查)】则只是简单的查找变量
- 【变量赋值】和【调用函数时传参】,这两种操作都会导致【LHS查询】
小测试,找出LHS查询和LHR查询
function foo(a){var b = a;return a + b;
}
var c = foo(2);
//LHR查询
foo(2
= a
a..
..b
//LHS查询
c =
b =
a = 2 (传参,隐式变量分配)
ReferenceError 和 TypeError
- 如果【RHS查询】在作用域中找不到需要的变量,引擎就会抛出 ReferenceError ,代作作用域判别失败
- 试图引用 null 或是 undefined 属性,会引发 TypeError,代表作用域判别成功,但是操作是非法的
eval 和 with
- eval 会动态插入一个变量声明,这会对词法作用域的环境进行修改
- with 被当作重复引用一个对象中的多个属性时的快捷方式,不必重复引用对象本身。这种方式相当于创建了新的词法作用域
- 这两种方式,当引擎在进行编译时,不能进行相关的性能优化,【不要使用】
//eval
eval("var c = 666");
console.log(c);
//width
var obj = {a:1,b:2,c:3
}
with(obj){a = 111;b = 222;c = 333;
}
console.log(obj);//{ "a": 111, "b": 222, "c": 333 }
匿名函数自执行表达式 | Immediately invoked function expression
- 有两种写法,都是一样的,如下
- 如果要在其内部,获取函数对象,只有一种方法,如下
- 不要用【匿名函数自执行表达式】,要使用【具名函数自执行表达式】,如下
(function(){console.log(1)})();//1
(function(){console.log(2)}());//2
// arguments.callee在函数内部调用函数的方法
(function(){console.log(arguments.callee);//
})();
//使用可描述的名称,能让代码不言自明
(function printName(){console.log("name")})();
(function printColor(){console.log("color")}());
try catch 属于块级作用域
使用块级作用域提升性能
- 如下,由于 setTimeout 引用了 color 变量,如果没有大括号,代码块一中的变量会一直保留给 setTimeout,不会被垃圾回收机制处理
- 而实际上,setTimeout 中只引用了 color,代码块一完全可以在执行完后释放,所以可以手动加上块级作用域
function doSomething(data){console.log(data);
}
// 代码块一
{const data = [1,2,3];doSomething(data);
}
const color = "green";
setTimeout(function(){//如果不需要data,则可以将代码块一,放在大括号中,这样垃圾会收机制会释放出这一部分内存//console.log(data);console.log(color);
},2000)
变量提升
小测试,输出啥
a = 2;
var a;
console.log(a);//2
-不是undefined,有变量提升
小测试,再试一下
console.log(a);//undefined
var a = 2;
- 不是2,也不会报ReferenceError,而是undefined
- 因为,【变量声明存在提升,但变量赋值不会】
你不知道的javascript[上]学习总结(第一部分1-3章)相关推荐
- 读书笔记-你不知道的JavaScript(上)
本文首发在我的个人博客:http://muyunyun.cn/ <你不知道的JavaScript>系列丛书给出了很多颠覆以往对JavaScript认知的点, 读完上卷,受益匪浅,于是对其精 ...
- 你不知道的javascript_你不知道的javascript(上)
第一章 作用域是什么 编译 作用域 作用域嵌套 javascript通常被归类为"动态"或者解释性语言,但事实上他是一门编译语言,与传统的编译语言不同的是,它不是提前编译的,编译结 ...
- javascript立体学习指南
javascript立体学习指南 第一章:首先了解javascript 首先,什么是javascript? JavaStrip出生于1995年,是一种文本脚本语言,成都装修公司是一种动态的.弱类型的. ...
- 你不知道的JavaScript 上卷读书笔记
看了<你不知道的JavaScript 上>,为了防止自己忘记,特此记下与我而言的部分重点 任何足够先进的技术都和魔法无异. --Arthur C. Clarke 作用域和闭包 编译原理 分 ...
- JavaScript完全学习手册 pdf电子书
编辑推荐: 详解JavaScriptmw内置对象和文档对象:覆盖函数.Ajax.DOM.XML.正则表达式.事件以及安全性:涵盖文字特效.图片特效.时间特效.窗体特效及菜单特效:窗内网提供技术支持. ...
- JavaScript笔记 | 作用域和闭包 |《你不知道的JavaScript(上卷)》第一部分
JavaScript | 作用域和闭包 | 读书笔记 读书笔记(自用) 来自<你不知道的JavaScript(上卷)>第一部分 作用域和闭包 1 作用域是什么 1.1编译的3个步骤 (1) ...
- 精读《你不知道的javascript》中卷
前言 <你不知道的 javascript>是一个前端学习必读的系列,让不求甚解的JavaScript开发者迎难而上,深入语言内部,弄清楚JavaScript每一个零部件的用途.本书< ...
- 精读《你不知道的 javascript(上卷)》
前言 <你不知道的 javascript>是一个前端学习必读的系列,让不求甚解的JavaScript开发者迎难而上,深入语言内部,弄清楚JavaScript每一个零部件的用途.本书介绍了该 ...
- 《你不知道的JavaScript上卷》知识点整理与读书笔记
各位路过的的大佬.求关注.求点赞.谢谢 第一部分 作用域和闭包 第1章 作用域是什么 1.1编译原理 1.2理解作用域 1.3作用域嵌套 1.5异常 第2章 词法作用域 2.1词法阶段 2.2欺骗词法 ...
最新文章
- rust(50)-图像(3)
- Memcached 运行状态
- NIO--Buffer
- 音视频技术开发周刊 | 172
- 小度拆卸_拆卸invokedynamic
- 中day参数介绍_浅谈生物制药中的 CHO 细胞培养工艺开发
- Oracle提示“ORA-04098:触发器‘XXX_TRIGGER’无效且未通过重新验证”
- Javascript项目
- 腾讯X5内核浏览器的使用
- 唐家三少的新作品《天珠变》的最近评论...
- 为什么要发明Hooks?
- OCR识别系列之一-----文档字符识别
- hash和btree索引的区别
- 〖Python 数据库开发实战 - MySQL篇㉘〗- MySQL 日期函数
- UMLChina建模竞赛第3赛季第8轮:交友辅助系统,赵雅芝
- 独立手机版营销推广落地页pbootcms模板落地页单页网站
- Sign Up VS Register Sign in VS Login
- 网易云音乐与阿里音乐牵手!后版权时代,在线音乐拼什么?
- 22点到凌晨5点是几个小时_寅时是几点到几点:3点-5点(24小时凌晨3时~凌晨5时)...
- 超全的 Vue 开源项目合集