搜索
简帛阁>技术文章>js便签笔记(12)——浏览TOM大叔博客的学习笔记 part2

js便签笔记(12)——浏览TOM大叔博客的学习笔记 part2

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); // 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

 

更多内容请关注我的微博

 

从零学习Java之旅Part2面向对象部分从零学习Java之旅Part2面向对象部分类和对象基本概念成员变量VS局部变量方法引用类型形式参数构造方法特殊语法thisstatic代码块codeblo
linux目录结构学习与简析by:授客QQ:1033553122接Part11查看CPU信息cat/proc/cpuinfoprocessor:0每个逻辑cpu唯一编号0N,编号到N则说明有N个逻辑C
1、物理层解决如何在连接各种计算机传输媒体上传输数据比特流,而不是具体传输媒体2、物理层主要任务:确定与传输媒体接口有关一些特性(定义标准)①机械特性②电气特性③功能特性④规程特性3、三种通信方
MyBatis:MyBatis前身就是iBatis,iBatis本是apache一个开源项目,2010年5月这个项目由apahcesofewarefoundation迁移到了googlecode
区块链工作原理对论文《区块链技术综述》学习注:本篇中图片来自于论文《区块链技术综述》张亮2017侵删文章目录区块链工作原理比特币工作原理默克尔树分布式账本账本存储模型加密货币与数字资产账本分类共
part1主要分析动态sql参数相关解析,对于xml>sql过程没有详细分析,此文补上。part1GO增加part2源码分析原因,工作中遇到一个bug,mybatis查询有个参数为0,导致拼接
1将mysql订单数据导入hive分区表(桶、倾斜【partition,bucket,skew】a>在Hive中新建分区表CREATETABLEIFNOTEXISTSHelloHiveo
引言:多线程编程/异步编程非常复杂,有很多概念和工具需要去学习,贴心NET提供Task线程包装类和await/async异步编程语法糖简化了异步编程方式。相信很多开发者都看到如下异步编程实践原则:实
Appium之Python运行环境搭建Part2by:授客QQ:1033553122实践环境参见Appium之Python运行环境搭建Part1环境部署1、安装AndroidSDK安装好后,配置AND
言NoSQL数据库在2012年左右成为流行模式,并引发了一场数据库革命,导致许多企业用基于NoSQL数据平台取代他们传统RDBMS技术。有趣是,现在这些公司中的许多人要么对他们做这样决定感到