用了一个星期把《你不知道的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. Delphi - Indy TIdMessage和TIdSMTP实现邮件的发送

    idMessage / idSMTP 首先对idMessage类的各种属性进行赋值(邮件的基本信息,如收件人.邮件主题.邮件正文等),其次通过idSMTP连接邮箱服务器,最后通过idSMTP的Send ...

  2. SDU暑期集训排位(4)

    SDU暑期集训排位(4) C. Pick Your Team 题意 有 \(n\) 个人,每个人有能力值,A 和 B 轮流选人,A 先选,B 选人按照一种给出的优先级, A 可以随便选.A 想最大化己 ...

  3. bzoj 1085骑士精神

    bzoj 1085骑士精神 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士,且有一个空位.在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2 ...

  4. Codeforces Round #409 C. Voltage Keepsake(二分+思维)

    题目链接:http://codeforces.com/contest/801/problem/C 题意:给出一个充电器每秒钟充p个点,还有n个电器要同时使用a[i]表示第i个电器每秒钟用多少点,b[i ...

  5. python控制台简单实现五子棋

    #棋盘#落子#规则import randomclass chess: def __init__(self): print('#---------------棋盘----------------#') ...

  6. Ansible实现批量管理服务器

    Ansible介绍: a. ansible是一个基于Python开发的自动化运维工具b. ansible是一个基于ssh协议实现远程管理的工具c. ansible软件可以实现多种批量管理操作(批量系统 ...

  7. 如何完美激活pycharm2019.2.2

    本号持续关注pycharm的更新,这不本月11号迎来新版本,为防走丢,请关注公众号,让我们携手并行!有道是"予人玫瑰手留余香",分享的确是件令人愉快的事,这也是我创建公众号的初心. ...

  8. 041 模块5-jieba库的使用

    目录 一.jieba库基本介绍 1.1 jieba库概述 1.2 jieba库的安装 1.3 jieba分词的原理 二.jieba库使用说明 2.1 jieba分词的三种模式 2.2 jieba库常用 ...

  9. linux中启动Zookeeper

    1.先把zookeeper的安装包解压在/usr/local,如下: 2.进入zookeeper目录,创建一个data目录 3.进入同级conf目录下,里面有zoo_sample.cfg,修改该文件名 ...

  10. JavaBean的学习

    一.什么是JavaBean JavaBean是一个遵循特定写法的Java类,它通常具有如下特点: 这个Java类必须具有一个无参的构造函数 属性必须私有化. 私有化的属性必须通过public类型的方法 ...