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. css,jQuery,js部分注释

    注释:在开头加上<!--,以-->结尾 alt属性,也被称为alt text, 是当图片无法加载时显示的替代文本 action属性的值指定了表单提交到服务器的地址 除了分别指定元素的 pa ...

  2. 使用Windows 8 Pro密钥光盘安装Windows 8.1 Pro

    在Windows 8.1发布接近半年的时候,自己终于腾出来了时间,准备升级一下自己的系统.作为一名极度强迫症患者,加上校园网的悲剧网速,最后决定使用光盘镜像全新安装而不是通过应用商店的升级. Figu ...

  3. [kuangbin]树链剖分A - Aragorn's Story

    比较水的题了,比模板题还要简单一点 理解了这个结构,自己打出来的,但是小错误还是很多,越来越熟练吧希望 错误函数updata,updata_lca,query||错误地方区间往下递归的时候是left ...

  4. 程序员、技术领导、管理者各有烦恼,你占了几条?ZZ

    Q1: 作为学生,你学习 SE的烦恼有哪些? http://blog.jobbole.com/101840/

  5. CentOS 7安装fail2ban+Firewalld防止SSH爆破与CC攻击

    准备工作 1.检查Firewalld是否启用 #如果您已经安装iptables建议先关闭 service iptables stop #查看Firewalld状态 firewall-cmd --sta ...

  6. SignalR 设计理念(一)

    SignalR 设计理念(一) 实现客户端和服务器端的实时通讯. 问题阐述 客户端提供的方法不确定! 客户端的方法参数不确定! 不同的名称和参数要分别调用指定的方法! 调用客户端方法时,忽略大小写! ...

  7. Linux Compile Multiple C++ Files

    Compile Two Files: $ CC -c Main.cc Sales_item.cc # by default generates a.exe # some compilers gener ...

  8. node - 使用request发送http请求

    在nodejs的开发中,有时需要后台去调用其他服务器的接口,这个时候,就需要发送HTTP请求了.有一个简单的工具可以用,Simplified HTTP request client,可以比较方便的模拟 ...

  9. 上下文相关的GMM-HMM声学模型续:参数共享

    一.三音素建模存在的问题 问题一:很多三音素在训练数据中没有出现(尤其跨词三音素) 问题二:在训练数据中出现过的三音素有相当一部分出现的频次较少 因此,三音素模型训练时存在较严重的数据不足问题 二.参 ...

  10. jq 复习帖子 常用操作

     1绝对定位(abs)与相对定位(relative)    区别是相对定位参照自己的位置进行移动(当然需要设置top left这些生效)并且原来的位置保留着 偏移后会把其它的层遮罩住    绝对定位就 ...