《你不知道的JavaScript(上)-作用域和闭包》学习笔记

1.编译原理:

(1)编译器、作用域、引擎
  • 编译器会忽略重复声明
  • 编译原理(p7):

例如:var a=2,编译器会进行如下处理:

  • 1.遇到var a,编译器会询问作用域是否已经有一个该名称的变量存在于同一个作用域的集合中。如果是,编译器会忽略该声明,继续进行编译;否则它会要求作用域在当前作用域的集合中声明一个新的变量,并命名为a
  • 2.接下来编译器会为引擎生成运行时所需的代码,这些代码被用来处理a=2这个赋值操作。引擎运行时会首先询问作用域,在当前的作用域集合中是否存在一个叫做a的变量。如果是,引擎就会使用这个变量;如果否,引擎会在外层嵌套的作用域中继续查找,直到找到该变量,或抵达最外层的作用域(也就是全局作用域)为止。
    【如果到最外层的作用域还未找到,引擎会抛出ReferenceError异常。】

注:
• 引擎:从头到尾负责整个 JavaScript 程序的编译及执行过程。
• 编译器:引擎的好朋友之一,负责语法分析及代码生成等脏活累活。(编译:词法解析-语法解析-代码生成。对于 JavaScript 来说,大部分情况下编译发生在代码执行前的几微秒(甚至更短!)的时间内。)
• 作用域:引擎的另一位好朋友,负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。

(2)LHS、RHS、ReferenceError、TypeError (p12)
  • LHS查询是试图找到变量的容器本身(赋值操作的左侧,如:var a = 2中的a),从而对其进行赋值;
  • RHS查询是取得它的源值。例如:console.log(a),需要对aconsole.log都进行RHS查询。
  • ReferenceError:同作用域判别失败相关。(以下详细说明)
  • TypeError:表示作用域判别成功了,但是对结果的操作是非法或不合理的。(以下详细说明)
  • 如果RHS查询在所有嵌套的作用域中遍寻不到所需的变量,引擎就会抛出ReferenceError异常。
  • 如果RHS查询找到了一个变量,但是你尝试对这个变量的值进行不合理的操作,比如试图对一个非函数类型的值进行函数调用,或者引用null或undefined类型的值中的属性,那么引擎会抛出TypeError异常。
  • 【非严格模式】如果LHS查询在最顶层(全局作用域)中也找不到目标变量,全局作用域中就会创建一个具有该名称的变量(全局变量),并将其返回给引擎。
  • 【严格模式】如果LHS查询在最顶层(全局作用域)中也找不到目标变量,不会创建并返回一个全局变量,引擎会抛出ReferenceError异常。

2.词法作用域

  • 逐级嵌套的作用域(作用域气泡)
  • 词法作用域:简单地说,词法作用域就是定义在词法阶段的作用域。换句话说,词法作用域是由你在写代码时将变量和块作用域写在哪里来决定的,因此当词法分析器处理代码时会保持作用域不变(大部分情况下是这样的)。
  • 欺骗词法作用域:eval(..)with函数,不过这两个方法无法被引擎优化,因此性能会降低,不推荐使用。

3.函数作用域和块作用域‌

  • 函数作用域的含义是指,属于这个函数的全部变量都可以在整个函数的范围内使用及复用(事实上在嵌套的作用域中也可以使用)。
  • 块作用域:withtry/catch的catchletconst

4.提升‌

  • 函数声明和变量声明都会被提升。
  • 变量声明提升,例如:
var a = 1;
foo();
function foo() {
    console.log( a ); // undefined 
    var a = 2;
}

相当于:

function foo() { 
    var a;
    console.log( a ); // undefined
    a = 2; 
}
var a;
a = 1;
foo();
  • 函数优先:函数声明和变量声明都会被提升,但函数会首先被提升,然后才是变量
  • 例如:
foo(); // 1
var foo;
function foo() {
  console.log(1);
}
foo = function() {
  console.log(2);
}

相当于:

function foo() {
  console.log(1);
}
var foo; //重复声明,被忽略
foo(); // 1
foo = function() {
  console.log(2);
}

5.作用域闭包

(1) for循环中let的妙用(p51)

for循环头部的let声明还会有一个特殊的行为。这个行为指出变量在循环过程中不止被声明一次,即每次迭代都会声明。随后的每个迭代都会使用上一个迭代结束时的值来初始化这个变量。
例如:

for(let i=1;i<=5;i++) {
  setTimeout(function() {
    console.log(i)
  },i*1000)
}

相当于:

for(var i=1;i<=5;i++) {
  let j=i;
  setTimeout(function() {
    console.log(j)
  },j*1000)
}
(2) 模块(p53)

模块模式需要具备两个必要条件:
1.必须有外部的封闭函数,该函数必须至少被调用一次(每次调用都会创建一个新的模块实例)。
2.封闭函数必须返回至少一个内部函数,这样内部函数才能在私有作用域中形成闭包,并且可以访问或者修改私有的状态。
【一个从函数调用所返回的,只有数据属性而没有闭包函数的对象并不是真正的模块】

  • 模块如下:
function CoolModule() {
  var something = "cool";
  var another = [1,2,3];
  function doSomething() {
    console.log(something);
  }
  function doAnother() {
    console.log(another.join());
  }
  return {
    doSomething: doSomething,
    doAnother: doAnother
  }
}
var foo = CoolModule();
foo.doSomething(); // cool
foo.doAnother(); // 1,2,3
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352