做用域
1. 全局做用域
2. 函数做用域
这里扯出来下js的函数声明和变量声明提高,直接来两段代码闭包
if (!a in window) { var a = 1; } console.log(a) //undefined
嗯,为何呢?由于var声明的变量会变量声明提高,因此至关于执行if判断的时候a变量已经声明过了,而此时a是一个全局变量既是window对象的一个属性,因此这里压根没有进if判断,因此这里打印出来的是undefined
再来一段坑坑的代码函数
(function (){ var a = b = 10; })() console.log(b) // b是10 console.log(a) // a是局部变量因此在这里打印a的时候会报错
在函数中var a = b = 10,b暴露为全局变量,由于赋值是从右往左进行的,也就是说这一行先执行b=1,这时候b就是全局变量了,没有被var过。而后是var a = b;a被声明了,是局部变量。你赋值给a,b=1,是不存在的,var a=b=1,就能够等同于,b=1;var a=b;this
那么下面这里的问题也很容易知道答案喽spa
var a; var b; (function () { console.log(a) // undefined console.log(b) //10 var a = b = 10; console.log(a); // 10 console.log(b); // 10 })(); console.log(a) // undefined console.log(b) // 10
做用域链是怎么回事呢code
1. 执行环境和做用域 (函数第一次调用的时候会建立做用域链和执行环境,并把做用域链赋值给一个内部属性[scope]),而后使用this、arguments和其余命名参数来初始化函数的活动对象。但在做用域链中,外部函数的活动对象始终处于第二位,外部函数的外部函数始终处于第三位...直至做用域链的终点全局执行环境。
2. 活动对象
3. 变量对象(每一个执行环境都会有一个变量对象)对象
先来个函数吧!!!blog
var a = 10, b = 20; function sum (a, b) { return a + b; } var result = sum(a, b)
// 在sum函数被调用的时候,会建立它的做用域和执行环境,而后,使用arguments和其余命名参数初始化其活动参数。在做用域链中,它的外部函数处于第二位,外部函数的外部函数处于第三位......,直到做用域链的终点全局执行环境内存
通常,在函数执行完毕后,局部活动对象就会销毁,内存中仅仅保存全局做用域(全局执行环境的变量对象)。作用域
闭包中的做用域链又是怎么回事呢???io
在另外一个函数内部定义的函数会将包含函数的活动对象添加到它的做用域链中。外部函数执行完后,虽然做用域链会销毁,可是因为内部函数仍然在引用这个活动对象,外部函数的活动对象不会销毁,一直保存到内存中,直到内部函数被销毁后,外部函数的活动对象才会被销毁。
闭包会携带包含他的函数的做用域链,因此比其余函数占用更多的内存。过分使用闭包会致使内存使用过多。