用了一个星期把《你不知道的JavaScript》看完了,但是留下了很多疑惑,于是又带着这些疑惑回头看JavaScript的内容,略有所获。

第二遍阅读这本书,希望自己能够有更为深刻的理解。

词法作用域

……如果是 有状态 的解析过程,还会赋予单词语义……

这本书是以编译原理的部份内容结合JavaScript来开篇的,所以如果没有学过编译原理,这一小部分内容显得有些晦涩。

虽然多数人没有接触过编译原理,但有一个东西必定知道,就是markdown语法。实际上,从markdown文件到HTML的过程就包含了词法化的过程。

那什么是有状态?粗略来讲,就是一个模式匹配的问题,或者可以认为是字符串的匹配:

源串:"str782yui",待匹配的串:"sj1" ,思考一下朴素匹配的算法,我们是要从头开始比较的,那么在每一次比较的时候,就两种状态,字符相同/不相同,每接受一个字符,就会走向其中一个状态。

这就是所谓的状态。当然了,这也只是一种粗浅的比喻,可能会有更好的。

说句心里话,编译原理是很有用的科目,但是真正学起来的时候还是挺痛苦的。

考虑以下代码:

function foo(a) {
  var b = a*2;
  function bar(c) {
      console.log(a, b, c);
  }
  bar(b*3);
}
foo(2);

在这个例子中有三个逐级 嵌套的作用域……

对于java程序员来说,一对花括号就可以限制变量的作用域,而且作用域之间的关系有 同级父子级 两种,同时还有包(package)这种很方便的东西。

但是JavaScript就不一样了,一对花括号是不能定义一个作用域的,而且由于var声明的变量存在变量提升,所以有些时候我们会发现某个变量并不能像预期的那样被约束在某对花括号中,于是就出现很多经典的问题。

JavaScript中函数和catch子块是能够创建作用域的,但是个人认为,为了创建一个作用域而使用catch子块,这等于是给catch增加了一个语义,二义性不好说,这可能会使程序变得不好阅读。但大家都这么做的话,那我也就随大流吧。

想起一个不知道从哪里传出来的笑话,说:catch不是异常处理关键字,而是流程控制语句。

提到了作用域,就一定要提变量的屏蔽,简单来说就一句话: 内部作用域的变量会屏蔽外部作用域的同名变量

那可能就有人问了,(上述代码)我通过foo.b这种方式能不能访问呢?

……想啥呢?想对象了是吧?不过可以通过window.foo这种方式来访问全局变量foo,为啥?这window不是一个全局的对象嘛,所有的全局变量都会自动的成为全局对象的属性。

……词法作用域查找 只会 查找一级标识符……

这句话就是在回答上面我提出来的问题。

function foo(str, a) {
  eval(str);
  console.log(a, b);
}
var b = 2;
foo("var b = 3", 1);

eval(..)调用中的"var b = 3;"这段diamante会被当做本来就在哪里一样处理……

这话说的好拗口啊?

有时候写程序的时候,我就会想,哎呀,要是能把一个字符串变成一个变量就好了,多方便啊。

eval差不多就是在完成这件事。书上说的这么绕,可能是为了可以让读者更好的理解。

在我看来,eval函数所做的就是动态的生成一段代码,插入到对应的位置上,变成了另一个程序,照此执行。

with声明实际上是根据你传递给它的对象凭空创建了一个 全新的词法作用域

到这里又增加了一个能够创建作用域的关键字。

var obj = {
    a: 1
};
with(obj) {
    a = 2;
    b = 3;
};

对上述代码,我们可以这么理解,with将obj声明为一个作用域,with内部的语句都是在这个作用域中的,so……

eval(..)和with会在运行时修改或创建新的作用域,以此来欺骗其他书写时定义的词法作用域。

eval是修改,with是创建作用域。

这两个都会导致程序性能的下降,原因是影响了编译优化,其实这俩就像是一个开关,任意一个存在时,都会打开禁止编译优化的按钮。就像是所谓的禁止指令重排一样。

总结

|ू・ω・` ):这本书真好看。

《你不知道的JavaScript》笔记(一)的更多相关文章

  1. python程序设计语言笔记 第一部分 程序设计基础

    1.1.1中央处理器(CPU) cpu是计算机的大脑,它从内存中获取指令然后执行这些指令,CPU通常由控制单元和逻辑单元组成. 控制单元用来控制和协调除cpu之外的其他组件的动作. 算数单元用来完成数 ...

  2. C程序设计语言笔记-第一章

     The C Programming language notes 一 基础变量类型.运算符和判断循环         char                 字符型  character      ...

  3. 北京大学Cousera学习笔记--6-计算导论与C语言基础--计算机的基本原理-认识程序设计语言 如何学习

    1.是一门高级程序语言 低级语言-机器语言(二进制) 汇编语言-load add save mult 高级语言:有利于人们编写理解 2.C语言的规范定义非常的宽泛 1.long型数据长度不短于int型 ...

  4. MOOC 编译原理笔记(一):编译原理概述以及程序设计语言的定义

    编译原理概述 什么是编译程序 编译程序指:把某一种高级语言程序等价地转换成另一张低级语言程序(如汇编语言或机器代码)的程序. 高级语言程序-翻译->机器语言程序-运行->结果. 其中编译程 ...

  5. 20145213《Java程序设计学习笔记》第六周学习总结

    20145213<Java程序设计学习笔记>第六周学习总结 说在前面的话 上篇博客中娄老师指出我因为数据结构基础薄弱,才导致对第九章内容浅尝遏止地认知.在这里我还要自我批评一下,其实我事后 ...

  6. javascript高级程序设计阅读笔记(一)

    javascript高级程序设计阅读笔记(一) 工作之余开发些web应用作为兴趣,在交互方面需要掌握javascript和css.HTML5等技术,因此读书笔记是必要的. javascript简介 J ...

  7. 《c++程序设计》笔记

    本文是学习谭浩强老师的<c++程序设计>后的笔记. 1.概述 c++是贝尔实验室在c语言的基础上发展而来,与c兼容.用c语言写的程序可以不加修改用于c++.从c++的名字可以看出它是c的超 ...

  8. 003-scanf函数使用和表达式-C语言笔记

    003-scanf函数使用和表达式-C语言笔记 学习目标 1.[掌握]输入函数scanf的基本使用方法 2.[掌握]输入函数scanf运行原理和缓冲区理解 3.[掌握]算术运算符和算术表达式的使用 4 ...

  9. 操作系统和程序设计语言的API使用的字符编码分析

     1.Java的运行环境中,String是什么编码? 使用java做程序设计语言,字符编码是和jvm相关的,和操作系统无关. java默认的编码是jvm在安装的时候就确定了的,它是根据你的系统的环境确 ...

  10. 扩展《C程序设计语言》练习2-3程序通用性

    最近开始自学C语言,在看K&R的<C程序设计语言>.练习2-3要求写一个函数,将输入的十六进制数字字符串转换成与之等价的整数值,配套答案没有扩展程序的通用性,所以我就稍微改造改造. ...

随机推荐

  1. 2013-2014 ACM-ICPC Pacific Northwest Regional Contest B.Bones’s Battery

    题意略. 思路: 这个题目求的是第一个可行解,由此想到用二分试探的方式来解决. 现在讲讲怎么验证该解是否合理: 先用floyd求出两两之间的最短距离. dp[ i ][ j ]表示,i 到 j 至少要 ...

  2. Docker swarm 获取service的container信息

    我们可以通过docker service create创建服务,例如: docker service create --name mysql mysql:latest 服务创建好后,如何来获取该ser ...

  3. 如果使用tf::transform进行简单的不同frame间的pose转换

    tf转换,分为两部分:broadcaster和listener.前者是tf的发布者,后者是接收者.我们如果要建立一个完整的tf体系,需要自己先生成tf信息用broadcaster发布出去,然后再在需要 ...

  4. TypeError: 'in <string>' requires string as left operand, not int

    报错 Traceback (most recent call last): File "D:/PyCharm 5.0.3/WorkSpace/2.NLP/9.DL在NLP中的应用/4. Ve ...

  5. [python]变量和赋值

    1. python的变量名以字母开头,包含字母.数字.下划线. 2. python是动态类型语言,即不需要预先声明变量的类型.变量的类型和值在赋值的时候被初始化. 变量赋值通过等号来执行. 代码: c ...

  6. HDU 1251 统计难题 字典树大水题

    今天刚看的字典树, 就RE了一发, 字典树原理还是很简单的, 唯一的问题就是不知道一维够不够用, 就开的贼大, 这真的是容易MLE的东西啊, 赶紧去学优化吧. HDU-1251 统计难题 这道题唯一的 ...

  7. 2018年全国多校算法寒假训练营练习比赛(第五场)H Tree Recovery

    Tree Recovery 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K,其他语言262144K 64bit IO Format: %lld 链接:https://w ...

  8. 徐州邀请赛 江苏 icpc I. T-shirt 矩阵快速幂

    题目 题目描述 JSZKC is going to spend his vacation! His vacation has N days. Each day, he can choose a T-s ...

  9. Disruptor框架中生产者、消费者的各种复杂依赖场景下的使用总结

    版权声明:原创作品,谢绝转载!否则将追究法律责任. Disruptor是一个优秀的并发框架,可以实现单个或多个生产者生产消息,单个或多个消费者消息,且消费者之间可以存在消费消息的依赖关系.网上其他博客 ...

  10. 【Nginx】简介以及安装、启动、关闭

    一.概述 二.Nginx基本安装 2.1 Windows安装Nginx Nginx目录结构 2.2 Linux安装Nginx 2.3 Mac利用homebrew安装 三.nginx启动关闭 3.1 重 ...