最近刚刚看完了《你不知道的 JavaScript》上卷,对 JavaScript 有了更进一步的了解。javascript
《你不知道的 JavaScript》上卷由两部分组成,第一部分是《做用域和闭包》,第二部分是《this 和对象原型》。下面我会按照简单介绍一下每一章的主要内容及阅读感觉。前端
第一部分《做用域和闭包》java
在这一章节中,做者经过引擎、编译器、做用域之间的对话,将这三者之间的关系及做用生动形象地展示出来,并引出了 LHS 查询和 RHS 查询的概念。设计模式
欺骗词法的方式:数组
eval()
;with
。这一章做者介绍了词法做用域以及欺骗词法的方式。说来惭愧,在看这章以前,我彻底没据说过「词法做用域」这个概念,一开始我还觉得是个很高大上的东西,看完以后你会以为其实也没什么,就是你平时都在写的东西,只不过你没有留意而已。微信
with
、try/catch
、let
、const
。这一章做者介绍了 JavaScript 中的函数做用域及块做用域,讲了函数声明和函数表达式的区别,其实很简单,就是看 function
这个关键字是不是在声明中的第一个词,若是是,那就是函数声明,不然就是函数表达式。另外,做者还简单地介绍了下 ES6 中具备块做用域做用的 let
和 const
关键字。闭包
在这以前,我一直觉得 ES6 以前是没有块做用域的,只有全局做用域和函数做用域,看完这章以后,我才知道其实在 ES3 的时候就有块做用域了。好比,with
。再好比,try/catch
中的 catch
,通常咱们是这样写的:app
try { // do something } catch (err) { console.log(err) }
其中这个 err
只存在 catch
分句内部,从别处引用时会抛出错误。这不就是块做用域吗?函数
这一章节做者简单地介绍了一下变量声明提高和函数声明提高。没什么好说的,须要注意的是函数表达式是赋值操做,并不会提高。性能
闭包是 JavaScript 中的一大难点,在这章中做者用了 4 个小节来介绍闭包,还有 1 个小节来介绍模块机制。不要看闭包有四个小节,其实也不过 8 页而已,核心的文字加起来也就 2 页,但就是这短短的 2 页,就把闭包给讲得很是清楚。
下面是书中给出关于闭包的定义:
当函数能够记住并访问所在的词法做用域时,就产生了闭包,即便函数是在当前词法做用域以外执行。
看了是否是仍是不懂,不要紧,让咱们来提取关键字:
再来看下书中的一段代码,看完以后再结合书中的定义来理解,我相信你对闭包确定会有更进一步的理解。
function foo() { var a = 2; function bar() { console.log(a); } return bar; } var baz = foo(); baz(); // 2 —— 朋友,这就是闭包的效果。
下面结合咱们刚刚提取的关键字来理解。
bar()
;bar()
当前所在的词法做用域是 foo()
的函数做用域。bar()
的词法做用域可以访问 foo()
的内部做用域。bar()
当作一个值类型传递给外部,在这句代码中 var baz = foo();
,咱们将 foo()
的返回值(也就是 bar()
)赋值给变量 baz
并调用 baz()
,实际上就是调用 bar()
。上面第 2 点里咱们说了,bar()
的做用域是 foo()
的函数做用域,可是,在这里,它倒是在本身定义的词法做用域之外的地方执行。怎么样,经过上面的分析,是否是对闭包有了进一步的理解了。
做者在这一章中简单地分析了下动态做用域,并经过一小段代码将它与词法做用域作了对比。词法做用域与动态做用域的主要区别在于:词法做用域是在定义时肯定的,而动态做用域是在运行时肯定的。
这一章简单地介绍了块做用域的替代方案 Traceur,以及所以可能会带来的性能问题。
这一章并无说明 this
机制 ,只是介绍了 ES6 中的箭头函数引入的行为 —— this
词法。关于 this
机制的详细说明是在第二部分《this 和对象原型》中的第 1 章和 第 2 章。
这一章做者致谢了一大堆的人,光人名的排版就占了两页多,说真的,我都怀疑是否是在凑字数了(纯调侃,没别的意思)。
第二部分《this 和对象原型》
这一章中做者先是提出咱们「为何要使用 this?」这个问题,而后再指出「this 究竟是什么?」,为第 2 章作铺垫。
这一章我我的认为最核心的就是两句话。第一句是「当一个函数被调用时,会建立一个活动记录(有时也称为执行上下文)。这个记录会包含函数在哪里被调用(调用栈)、函数的调用方式、传入的参数等信息。this
就是这个记录的一个属性,会在函数执行的过程当中用到」。也就是说,this
是活动记录里的一个属性,与函数执行的过程有关。
第二句话是「this 其实是函数被调用时发生的绑定,它指向什么彻底取决于函数在哪里被调用。」。第 2 章实际上就是在讲这个绑定。
默认绑定;
call()
、apply()
、bind()
;做者在这一章中全面介绍了 this
的绑定规则。
要弄清楚 this
的绑定对象,须要明白如下两点:
什么是调用位置?简单来讲,就是函数在代码中被调用的位置。为了找到调用位置,咱们须要分析调用栈,也就是为了到达当前执行位置所调用的全部函数,而调用位置就在当前正在执行的函数的前一个调用中。
而绑定规则就是说 this
绑定的对象是有规则的,而且这些规则是有优先级的,总的来讲有下面四点:
new
调用的,绑定到新建立的对象;call
、apply
、bind
调用的,绑定到指定的对象;undefined
,在非严格模式下绑定到全局对象。固然了,ES6 中新增的箭头函数并不在这四条规则里面,而是继承外层第一个非箭头函数调用的 this
绑定。
在看这一章以前,我对 this
只知其一;不知其二,网上找的答案也是五花八门,根本不知道哪一个对哪一个错。在看完这一章以后,我算是对 this
的所绑定的对象有了较为清晰的认识,之后再遇到相似的问题时,直接套用上面的规则就能够了。
这一章讲到了不少平时我并无注意到的东西,好比,通常来讲,咱们使用数组的时候都是下标/值对,可是,给数组添加属性竟然也是能够,虽然这并不会改变数组的长度。当我看到这一部分的内容时内心在想:我去,这是什么骚操做?这样竟然也能够?后面想了想,数组其实也是对象,是一个特殊的对象,从这一方面来讲也是行得通的;再好比,属性访问与赋值时发生的 [[Get]] 操做与 [[Put]] 操做,可以更好地了解其工做原理;还有,咱们能够利用 ES6 中的 Iterator 接口实现本身的迭代逻辑。
这一章讲到了 “类” 这一设计模式,以及 JavaScript 中各类实现这一模式的方法。
这一章的核心就是:类的本质是复制,多态和继承也是。这一点很重要,JavaScript 中也有类,可是二者的本质是不一样的,这一点在《第 5 章 原型》和《第 6 章 行为委托》里面有详细的说明。
这一章一开始看的时候我是很模糊的,由于做为一名 JavaScript 开发者,说实话我对于 “类” 这个东西的理解不是很明白,因此我跳过了这一章,等到看完了后面三章以后再回过来看,瞬间感受清晰不少了。
这一章中,第一小节的 [[Prototype]] 属性能够和第 3 章中的 [[Put]] 操做结合一块儿看,这样可以完整的了解属性赋值的工做原理;属性设置和屏蔽这一部分能够和第 4 章结合着阅读,以便更好地了解 JavaScript 中的类与其它语言中的类的区别。
这一章做者主要从类理论与委托理论(其实也就是对象关联)两种不一样的设计模式来介绍他们之间在代码上实现的不一样,能够看作是第 4 章和第 5 章的对象关联的实践部分。
这一章做者分析了 ES6 中新增的 Class 语法的优势与缺点。
全书感悟
以上就是本书中的一些主要内容介绍,我写得比较简单,其实书中还有不少比较细小的东西,有兴趣的同窗能够去买来看看。总的来讲,这本书仍是挺不错的,能让你学到一些平时没有注意到的东西,做者偏向于用口语化的文字来介绍知识点,不会显得枯燥。
最后,抛块砖,但愿能引块玉。下面是我在阅读本书过程当中的作的思惟导图。导图的内容比较多,不是很简洁,由于我但愿尽可能把书中做者提到的概念提取出来,因此可能会显得比较啰嗦。
最后,欢迎关注个人微信公众号:前端路漫慢。