Variable & Scope

Argument Passing:

Passing by value only. creates reference value but refer to the same object in the heap.

Determining Type:

typeof for primitive type; instanceof for object by checking prototype chain.

Execution Context and Scope(执行环境和作用域):

函数或变量的执行环境定义其对数据的读取权限。当收到代码执行命令时,当前函数的执行环境会被push进环境栈里。执行结束后pop出栈。在执行代码时,作用域链被创造出来。作用域就是当前环境下变量数据的可读性,作用域链即是其集合。这样不同作用域下同名变量不会冲突,起到隔离变量的作用。
eg,一个function的作用域:arguments ->来自context1的变量对象 ->来自 context2 -> context3 …
作用域是分层的,内层单向访问外层。

Var - Function Scope:

var把变量加到最近的上下文,函数内就是当前函数的上下文。如果不declare,那就加入全局上下文。同时,变量会被提升到当前上下文的顶部,这叫变量提升。

Let - Block Scope:

块作用域,{}内定义的作用域。

Const - Block Scope:

常数。object不能改reference,能改object内部的key。Object.freeze()锁定object内容使其完全不能被修改。

*Memory

Garbage Collection:

Mark-n-Sweep:垃圾收集机制周期性运行。当变量进入上下文,变量会被标记为在上下文内,这些是不能移除的。当变量离开上下文,就标记为离开。但收集机制运行时,所以在内存的变量,锁定在上下文内的和被引用的,然后剔除离开的。
Reference Counting:先算每个变量的引用次数。执行时,引用一次-1,到0就删除。痛点在循环引用。
*DOM和BOM的对象本质是C++的COM对象(跨编程语言通信用的一种标准),他们使用reference counting为垃圾收集手段。即便浏览器使用Mark-n-Swap,但假如循环引用发生在DOM object 和 js object间,还是会出现循环引用的问题。这是在执行结束后记得把对象设置成null清理内存。

Managing Memory:

从优化的角度看,开发者应该尽量让内存里仅保留必要的数据,可以废弃的数据应该及时标记为null。标记为null虽然不会立刻释放内存,但收集机制可以定位清除它们。这种优化对全局变量尤为重要,本地变量在被推出上下文会自动消除。
多用let/const 也能帮助收集机制快速定位废弃数据。
小心内存泄漏!!!两个例子:
Javascript自学系列:Variable, Scope & Memory

相关文章: