作用域 scope
作用域链精解
[[scope]]
:每个JavaScript
函数都是一个对象,对象中有些属性我们可以访问,但有些不可以,这些属性仅提供JavaScript
引擎存取,[[scope]]
就是其中一个。
[[scope]]
指的就是我们所说的作用域,其中存储了运行期上下文的集合。
作用域链:[[scope]]
中所存储的执行期上下文对象的集合,这个集合呈链式链接,我们把这种链式链接叫做作用域链
。
运行期上下文:当函数执行时,会创建一个成为执行期上下文
的内部对象。一个执行期上下文定义了一个函数执行时的环境,函数每次执行时对应的执行上下文都是独一无二的,所以多次调用一个函数会导致创建多个执行上下文,当函数执行完毕,它所产生的执行上下文被销毁。
function fn() {
//代码逻辑
}
fn(); // 执行期上下文
fn(); // 执行期上下文,使用完销毁
……
查找变量:从作用域链的顶端依次向下查找。函数自身的作用域,在作用域链的顶端。
function a() {
function b() {
function c() {
}
c();
}
b();
}
a();
/* 作用域链
a 定义 a.[[scope]] ==> 0 : GO
a 执行 a.[[scope]] ==> 0 : aAO
1 : GO
b 定义 b.[[scope]] ==> 0 : aAO
1 : GO
b 执行 b.[[scope]] ==> 0 : bAO
1 : aAO
2 : GO
c 定义 c.[[scope]] ==> 0 : bAO
1 : aAO
2 : GO
c 执行 c.[[scope]] ==> 0 : cAO
1 : bAO
2 : aAO
3 : GO
*/
立即执行函数
此类函数没有声明,在一次执行后即释放。适合做初始化工作,只执行一次的函数。
只有表达式才能被执行。
(function () {
var a = 123;
var b = 234;
console.log(a + b); // 357
}())
//带参数
//上面括号是形参,下面括号是实参。
(function (a, b, c) {
console.log(a + b + c) // 6
}(1, 2, 3))
//带返回值
var num = (function (a, b, c) {
var d = a + b + c;
return d;
}(1, 2, 3))
console.log(num);
写法
(function([形参]){}([实参]))
W3C官方建议这种写法
(function([形参]){})([实参])
//只有表达式才能被执行符号执行
function test() {
console.log(123)
}() //error
var test = function () {
console.log(123)
}() //123
在函数声明前面+
-
!
符号,可以把函数声明变成表达式,可让函数立即执行。但放弃了函数名字。
! function test() {
console.log(123)
}()
//
// 如果再执行test(),会报错。
// Uncaught ReferenceError: test is not defined
凡是表达式都能立即执行
function test(a, b, c, d) {
console.log(a + b + c + d);
}(1, 2, 3, 4)
//不报错,但不执行。说的准确点是函数不自执行。
//浏览器会解析为test()函数和多个表达式(1, 2, 3, 4)
//两者没关系。
闭包
内部的函数保存到了外部,就是闭包。
闭包将造成原有作用域链不释放,造成内存泄漏。
// e.g
function a() {
function b() {
var bbb = 234;
console.log(aaa);
}
var aaa = 123;
return b;
}
var glob = 100;
var demo = a();
demo();
// e.g
function a() {
var num = 100;
function b() {
num ++;
console.log(num)
}
return b;
}
var demo = a();
demo(); // 101
demo(); // 102
作用
实现共有变量
//累加
function add() {
var count = 0;
function num() {
count++;
console.log(count);
}
return num;
}
var addNum = add();
addNum(); //1
………
可以做缓存(存储结构)
function demo() {
var num = 100;
function a() {
num++;
console.log(num);
}
function b() {
num--;
console.log(num);
}
return [a, b]
}
var demoArr = demo();
demoArr[0](); // 101
demoArr[1](); // 100
网友评论