你不知道的JavaScript上卷

JavaScript和Java的关系就像Carnival和Car的关系一样,八竿子打不着。

JavaScript易上手,但由于其本身的特殊性,相比其他语言能真正掌握JavaScript的人比较少。JavaScript语言本质上有许多复杂的概念,但却用一种看起来比较简单的方式体现出来,比如回调函数。JavaScript开发者只是简单使用这些特性而不会去关心语言内部的实现原理。

阿喀琉斯之踵

不要满足于只是让代码正常工作,而是弄清楚为什么,拥抱整个JavaScript

知其然,也要知其所以然


代码示例、练习题

Safari Books Online 数字图书馆,同时以图书和视频的形式出版世界顶级技术和商务作家的专业作品。


第1章 作用域是什么

需要设计一套设计良好的规则来存储变量,并且在之后可以方便的找到这些变量。这套规则叫作用域

源代码-->>编译-->>执行

编译:

  • 分词/词法分析 Tokenizing/Lexing

    将由字符组成的字符串分解成有意义的代码块(于该门语言而言),这些代码块叫作词法单元token。var a = 2; ==>> var、a、=、2、;。空格是否会被当成词法单元取决于空格在该门语言中的意义。

    分词tokenizing和词法分析lexing之间的细微区别:

    差异在于词法单元的识别是通过有状态还是无状态的方式进行(换句话说,如果词法单元生成器在判断a是一个独立的词法单元还是其他词法单元的一部分时,调用的是有状态的解析规则,那这个过程就叫作词法分析)

  • 解析/语法分析 Parsing

    将词法单元流(数组)转换成一个由元素逐级嵌套所组成的代表程序语法结构的树。抽象语法树Abstract Syntax Tree,AST。var a = 2;的抽象语法树中可能有一个叫作VariableDeclaration的顶级节点,然后是一个叫作Identifier(它的值是a)的子节点,以及一个叫作AssignmentExpression的子节点。AssignmentExpression节点有一个叫作NumericLiteral(值是2)的子节点。

  • 代码生成

    将AST转换成可执行代码。与语言、目标平台相关。就是用某种方法将var a = 2;的AST转化为一组机器指令,用来创建一个叫作a的变量(包括分配类存),并将一个值储存在a中。

    这是引擎如何管理系统资源的内容

JavaScript引擎在语法分析、代码生成阶段有特定的步骤来对运行性能进行优化,包括对冗余元素进行优化等。JavaScript任何的代码片段的编译过程发生在代码执行前的几微秒内,JavaScript引擎用尽各种办法(比如JIT,可以延迟编译甚至实施重编译)来保证性能最佳。比如JavaScript编译器首先会对var a = 2;进行编译然后作好执行它的准备。


引擎 从头到尾负责整个JavaScript程序的编译及执行

编译器 负责语法分析、代码生成等脏活累活

作用域 负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限


var a = 2;

引擎认为这里有两个完全不同的声明:一个由编译器在编译时处理,另一个由引擎在运行时处理。

上面三者协作的过程:编译器分解成词法单元并将其解析成一个树结构 ==>> 代码生成

代码生成过程:遇到var a,编译器询问作用域是否已经有一个该名称的变量存在于同一个作用域的集合中。是 ==>> 编译器跳过该声明;否 ==>> 要求作用域在当前作用域集合声明一个新变量a。为引擎生成运行时所需代码,这些代码用于处理a = 2这个赋值操作。引擎运行时会首先询问作用域,在当前作用域集合中是否存在a变量,是 ==>> 引擎使用该变量;否 ==>> 引擎会继续查找该变量。

如果引擎找到了a变量,会将2赋值给它。否则引擎抛出异常。


引擎查询变量的方式: LHS查询 RHS查询

LHS查询:变量出现在赋值操作的左侧。试图找到变量容器本身从而对其赋值。a = 2

RHS查询:变量出现在赋值操作的右侧。简单地查找某个变量的值。console.log(a)

既有LHS又有RHS:

function foo(a) { // 形参a
console.log(a); // 2
}
foo(2); // 隐式的a=2操作

作用域嵌套 一个块或函数嵌套在另一个块或函数中。在当前作用域中无法找到某个变量时,引擎就在外层嵌套的作用域中继续找,直到找到或抵达最外层作用域(全局作用域)为止。

RHS查询不到所需变量,引擎抛出ReferenceError异常

LHS查询时,如果在全局作用域也无法找到目标变量,在全局作用域中就会创建一个该名称的变量,并将其返还给引擎。(前提是程序运行在非"严格模式"下,hack做法严格禁止自己使用),在严格模式下,引擎也是抛出"ReferenceError异常"

RHS查询找到一个变量,但你尝试对这个变量的值进行不合理操作,比如试图对一个非函数类型的值进行函数调用,或者引用null或undefined类型的值的属性,引擎会抛出另一种类型异常TypeError

  • ReferenceError 同作用域判别失败相关
  • TypeError 代表作用域判别成功但对结果的操作非法或不合理

为JavaScript正名--读你不知道的JavaScript(持续更新..)的更多相关文章

  1. JavaScript资源收集分享,持续更新中。。。

    平时收集的一些JavaScript资源,分享给大家 jQuery UI jEasyUI Extensions http://jqext.sinaapp.com 布局做的挺不错,有比较复杂的菜单导航.P ...

  2. JavaScript词法作用域—你不知道的JavaScript上卷读书笔记(一)

    前段时间在每天往返的地铁上抽空将 <你不知道的JavaScript(上卷)>读了一遍,这本书很多部分写的很是精妙,对于接触前端时间不太久的人来说,就好像是叩开了JavaScript的另一扇 ...

  3. javascript/jquery 常见功能实现(持续更新...)

    1. input 只能输入整数数字和字母 $(document).on('keyup','#no',function(){ var val = $.trim($(this).val()); if(va ...

  4. JavaScript中常用函数(入门级)(持续更新)

    本文中枫竹梦介绍一些JavaScript中入门级的常用函数,对于已经过了入门的童鞋可选择略过,都是一些非常实用的函数.如果发现什么问题,欢迎讨论. 问题列表 Q1: 设计一个函数repeatIt(st ...

  5. JavaScript设计模式小抄集(持续更新)

    前言 本文旨在记录JavaScript中常用的设计模式代码片段,简要说明使用场景,不过于追究细节.在设计模式开篇之前,还是先要搞清楚JavaScript中关于面向对象的基础知识,可以先看看JavaSc ...

  6. [已读]你不知道的JavaScript(上卷)

    就在前幾天,我在看完第一部分的時候,說它在我心中要超過蝴蝶書了,好吧,現在要收回這句話.第二部分的內容著重在ecma5,6對象的新特性的介紹,深度上就一般啦,沒什麼收穫.總體來說,這本書詞法作用域,作 ...

  7. ( 译、持续更新 ) JavaScript 上分小技巧(三)

    最近家里杂事较多,自学时间实在少的可怜,所以都在空闲时间看看老外写的内容,学习之外顺便翻译分享~等学习的时间充足些再写写自己的一些学习内容和知识点分析(最近有在接触的:复习(C#,SQL).(学习)T ...

  8. ( 译、持续更新 ) JavaScript 上分小技巧(一)

    感谢好友破狼提供的这篇好文章,也感谢写这些知识点的作者们和将他们整理到一起的作者.这是github上的一篇文章,在这里本兽也就只做翻译,由于本兽英语水平和编程能力都不咋地,如有不好的地方也请多理解体谅 ...

  9. 【前端】Util.js-ES6实现的常用100多个javaScript简短函数封装合集(持续更新中)

    Util.js (持续更新中...) 项目地址: https://github.com/dragonir/Util.js 项目描述 Util.js 是对常用函数的封装,方便在实际项目中使用,主要内容包 ...

随机推荐

  1. 全屏使用swiper.js过程中遇到的坑

    概述 swiper.js确实是一个很好用的插件,下面记录下我在全屏使用过程中遇到的一些坑和解决办法,供以后开发时参考,相信对其他人也有用. 通用方案 一般来说,swiper需要放在body的下一层,虽 ...

  2. typescript-koa-postgresql 实现一个简单的rest风格服务器 —— typescript 开发环境配置

    最近需要用 nodeJS 写一个后台程序,为了能够获得 IDE 的更多代码提示,决定用 typescript 来编写,随便也学习下 ts,在这记录下实现过程. 1.新建文件夹 typescript-k ...

  3. [Leetcode]315.计算右侧小于当前元素的个数 (6种方法)

    链接 给定一个整数数组 nums,按要求返回一个新数组 counts.数组 counts 有该性质: counts[i] 的值是  nums[i] 右侧小于 nums[i] 的元素的数量. 示例: 输 ...

  4. Django模版语言自定义标签-实现前端 关联组合过滤查询

    前端关联 组合过滤查询 实现效果如图: models.py 创建表代码 from django.db import models # Create your models here. class Le ...

  5. Redis笔记(4)独立功能的实现

    1.前言 本节记录一下redis的一些功能上的实现,包括发布订阅.事务.Lua脚本.排序.二进制位数组.慢查询日志和监视器. 2.发布订阅 上一章介绍sentinel的时候说到了sentinel会订阅 ...

  6. Java模式—静态代理模式

        静态代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问,提供“真实对象”的代表,在访问对象时引入一定程度的间接性,这种间接性可以附加多种用途. 代理模式的主要作用是为其他对象 ...

  7. tensorflow进阶篇-5(反向传播2)

    上面是一个简单的回归算法,下面是一个简单的二分值分类算法.从两个正态分布(N(-1,1)和N(3,1))生成100个数.所有从正态分布N(-1,1)生成的数据目标0:从正态分布N(3,1)生成的数据标 ...

  8. setPreferredContentSize error in ios app

    Creating "IOS Project" in xcode 5 causes the following when launching for iPad simulator. ...

  9. JAVA微信服务号开发简记

    现在微信公众平台的开发已经越来越普遍,这次开发需要用到微信公众平台.所以这边做一个简单的记录,也算是给那些没踩过坑的童鞋一些启示吧.我将分几块来简单的描述一下,之后会做详细的说明. 基本认证信息说明 ...

  10. js便签笔记(11)——浏览TOM大叔博客的学习笔记 part1

    1. 前言 这两天看了一下TOM大叔的<深入理解js系列>中的基础部分,根据自己的实际情况,做了读书笔记,记录了部分容易绊脚的问题.写篇文章,供大家分享. 2. 关于HTMLCollect ...