1. 前言

昨天写了《js便签笔记(11)——浏览TOM大叔博客的学习笔记 part1》,简单记录了几个问题。part1的重点还是在于最后那个循环创建函数的问题,也就是多个子函数公用一个闭包数据的问题。如果觉得有兴趣,可以再重新翻出来看看。

今天继续把剩下的问题写完。

2. 作用域链

学js的人,即使初级入门的也都知道“原型链”,但是“作用域链”,可能好多人没有听说过。大部分人都知道或者听说过“闭包”,但是可能有好多人不知道闭包其实和作用域链有莫大的联系。如果理解闭包不从作用域链开始理解,那么你就只能理解闭包的皮毛。

我也是从TOM大叔的这些博客中才了解到作用域链的,之前也看过了许多本书籍,都没有很清晰的展开作用域链这个概念。其实作用域链简单说来也好理解,如下代码:

        var x = 10;
function fn() {
var y = 20;
return function () {
var z = 30
console.log(x + y + z);
}
}

上面代码中,如果想要打印 x+y+z 的值,就必须要遍历三个层次的上下文环境或者作用域,这其实和原型链的结构表现形式类似。但要细细将来,连同闭包图文并茂的说明白,需要很多内容。

此处不再深入进去,以后有机会再另起一篇详细介绍。

3. 二维链查找

上文讲到通过作用域练向上查找变量,实际在查找变量的过程中,是使用“二维链查找”——“作用域链” + “原型链”。看如下代码:

       Object.prototype.x = 10;
function fn() {
var y = 20;
return function () {
var z = 30
console.log(x + y + z);
}
}

这份代码跟上文中演示作用域链的代码差不多,但是它却通过 Object.prototype.x = 10; 这么一句话,表现出了原型链在其中的作用。
因此,在查找变量值时,是同时兼顾原型链和作用域链两个方向的,即“二维链查找”。

4. 独立作用域只能通过函数来创建

这句话的下半句是——不能通过if/for等语句块来创建。后半句大家可能知道,但是它的本质确实前半句——独立作用域只能通过函数来创建(除了独立作用域之外,剩下的就是全局作用域)。既然独立作用域只能通过函数来创建,那么函数中任何地方的自由变量就都是函数层级的,因此,以下代码希望不要再次出现:

5. 隐式全局变量的本质

var a = 10;
b = 20;

以上两句代码,看似都是声明两个全局变量,但是按照TOM大叔说的,只有var才能声明一个变量,也就是 var a = 10; 是真正的声明变量。

而下一句 b = 20,其实是相当于设置window的一个属性值而已。

因此,第一句的本质是声明一个全局变量;第二句的本质是设置window的一个属性值。

当然,不推荐用第二句的形式。

6. 函数声明和函数表达式的不同

js定义函数的方法有多种,但看看以下这段代码:

fn();
var fn = function() { //函数表达式
alert(123); // 报错
}
//------
fn();
function fn() { //函数声明
alert(123); //
}

两种函数定义方式,却得出不一样的结果。

此处我当时没有详细看,因为这样使用的情况不是很多,所以就没有过深入的细看,只是做了个标记。如果有了解的朋友,不放解释一下。

7.js使用静态作用域

在part1中讲过,当一个函数作为参数被传入,后者作为一个值被返回的时候,连同它一块被传递的,是它的作用域。也就是咱们常说的闭包。且看如下代码:

var x = 10;
function foo() {
alert(x);
}
(function (funarg) {
var x = 20;
funarg(); // 10, 不是20
})(foo);

foo是一个函数,把它作为参数传入进另一个函数中执行,连同一起传递的,是foo的作用域。而foo使用的是静态作用域,其中的变量x在传递的时候已经被静态赋值,不会受其他环境下x变量的影响。
这个道理也同样适用于函数作为返回值。如下:

function fn() {
var x = 10;
return function () {
alert(x);
}
}
var ret = fn();
var x = 20;
ret(); // 10,不是20

更多内容请关注我的微博

js便签笔记(12)——浏览TOM大叔博客的学习笔记 part2的更多相关文章

  1. javascript - 浏览TOM大叔博客的学习笔记

    part1 ---------------------------------------------------------------------------------------------- ...

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

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

  3. hexo博客的学习笔记

    这篇文章主要的作用是作为 .md文件打开,内部的格式为一个初学者对hexo以及markdown语法运用的笔记 1.Hexo的写文格式 最开始为文章的属性部分,以三横杠-开始,-结束.里面记录了文章的标 ...

  4. Git--廖雪峰的博客的学习笔记

    为了督促自己能看完这个网站的学习教程,边看边做了些简要的笔记,记录了常用命令,其实也就是自己打了些简单的命令,好多直接就粘贴过来了,也算是一个学习的证明吧,想按详细的教程,还是要去博主的园子学习啊地址 ...

  5. 我的第一篇博客----LCS学习笔记

    LCS引论 在这篇博文中,博主要给大家讲一个算法----最长公共子序列(LCS)算法.我最初接触这个算法是在高中学信息学竞赛的时候.那时候花了好长时间理解这个算法.老师经常说,这种算法是母算法,即从这 ...

  6. js便签笔记(2)——DOM元素的特性(Attribute)和属性(Property)

    1.介绍: 上篇js便签笔记http://www.cnblogs.com/wangfupeng1988/p/3626300.html最后提到了dom元素的Attribute和Property,本文简单 ...

  7. ibatis 学习笔记 3 - pfpfpfpfpf的专栏 - 博客频道 - CSDN.NET

    body { font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI ...

  8. OpenGL ES 学习笔记 - Overview - 小旋的博客

    移动端图形标准中,目前 OpenGL ES 仍然是比较通用的标准(Vulkan 则是新一代),这里新开一个系列用于记录学习 OpenGL ES 的历程,以便查阅理解. OverView OpenGL ...

  9. sql server 关于表中只增标识问题 C# 实现自动化打开和关闭可执行文件(或 关闭停止与系统交互的可执行文件) ajaxfileupload插件上传图片功能,用MVC和aspx做后台各写了一个案例 将小写阿拉伯数字转换成大写的汉字, C# WinForm 中英文实现, 国际化实现的简单方法 ASP.NET Core 2 学习笔记(六)ASP.NET Core 2 学习笔记(三)

    sql server 关于表中只增标识问题   由于我们系统时间用的过长,数据量大,设计是采用自增ID 我们插入数据的时候把ID也写进去,我们可以采用 关闭和开启自增标识 没有关闭的时候 ,提示一下错 ...

随机推荐

  1. lua rc4算法实现

    由于项目需要,用python django写restful接口遇到瓶颈,python django+uwsgi处理请求是会阻塞的, 如果阻塞请求不及时处理,会卡住越来越多的其它的请求,导致越来越多的5 ...

  2. 关于memcached

    代振军 http://www.cnblogs.com/daizhj/archive/2009/03/23/1386652.html http://www.cnblogs.com/daizhj/arch ...

  3. Codeforces821B Okabe and Banana Trees 2017-06-28 15:18 25人阅读 评论(0) 收藏

    B. Okabe and Banana Trees time limit per test 2 seconds memory limit per test 256 megabytes input st ...

  4. hdu 4941 map的使用

    http://acm.hdu.edu.cn/showproblem.php?pid=4941 给定N,M和K,表示在一个N*M的棋盘上有K个棋子,给出K个棋子的位置和值,然后是Q次操作,对应的是: 1 ...

  5. ASP.NET Web API 框架研究 IoC容器 DependencyResolver

    一.概念 1.IoC(Inversion of Control),控制反转 即将依赖对象的创建和维护交给一个外部容器来负责,而不是应用本身.如,在类型A中需要使用类型B的实例,而B的实例的创建不是由A ...

  6. CRC校验3种算法_转载

    //CRC16校验在通讯中应用广泛,这里不对其理论进行讨论,只对常见的3种//实现方法进行测试.方法1选用了一种常见的查表方法,类似的还有512字//节.256字等查找表的,至于查找表的生成,这里也略 ...

  7. spark Graph 的PregelAPI 理解和使用

    spark Graph 的PregelAPI 理解和使用 图本质上是一种递归的数据结构,可以使用Spark GraphX 的PregelAPI接口对图数据进行批量计算, 之前一直不怎么理解Pregel ...

  8. [NOI2017]蔬菜(贪心)

    神仙题啊! 早上开了两个多小时,终于肝出来了,真香 我们考虑从第 \(10^5\) 天开始递推,先生成 \(p=10^5\) 的解,然后逐步推出 \(p-1,...,2,1\) 的解. 那怎么推出 \ ...

  9. 09_python_初始函数

    一.定义 函数是对功能和动作的封装 def functionname( parameters ): "函数_文档字符串" function_suite return [expres ...

  10. 堆排序(大顶堆、小顶堆)----C语言

    堆排序 之前的随笔写了栈(顺序栈.链式栈).队列(循环队列.链式队列).链表.二叉树,这次随笔来写堆 1.什么是堆? 堆是一种非线性结构,(本篇随笔主要分析堆的数组实现)可以把堆看作一个数组,也可以被 ...