Javascript Scope

The extent of a scope refers to the lifetime of a variable (i.e., how long a variable holds a certain value)

Global Scope

Javascript中任意不使用var创建的变量具有全局作用域。

global
1
2
3
4
5
6
7
8
9
10
globalVariable = "global";
(function() {
console.log(globalVariable);
})()

-> global

delete globalVariable;

-> true

当然,任意定义在文件最顶层的变量,事实上,由于Javascript Hositing作用,所有定义在最外层的变量都会被提升至作用域首部,都具有全局作用域。

值得注意的是使用var定义的变量是不能delete的,它不是全局变量的属性:

del_variable
1
2
3
4
var globalVariable = 'global';
delete globalVariable;

-> false

除此之外,任意被暴露到最外层的变量,一旦被全局作用域捕获,其本身都会存在被随意修改的风险。

Lexical Scope

Lexical scope refers to the visibility of a variable and its value analogous to its textual representation.

Javascript会从内向外寻找变量的绑定,所以变量的定义距离使用处最近,则该变量会被使用。

lexical_scope
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function lexicalScope() {
var lexicalVariable = "outer";
if(true) {
var lexicalVariable = "inner";
console.log(lexicalVariable);
(function(){
var lexicalVariable = "innerMost";
console.log(lexicalVariable);
})();
console.log(lexicalVariable);
}
}

lexicalScope();
-> inner
innerMost
inner

Dynamic Scope

the value of any given binding cannot be known until the caller of any given function is known— which may be too late.

dynamic_scope
1
2
3
4
5
6
7
function globalThis() { return this; }
globalThis();
-> some global object, probably Window
globalThis.call('barnabas');
-> 'barnabas'
globalThis.apply('orsulak', [])
-> 'orsulak'

在Javascript中,this所处的作用域就是动态作用域。也就是说,globalThis()返回值完全由调用方决定,this变量的对照表是不断改变的。更多参考这里

Function Scope

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function strangerIdentity(n) {
for(this['i'] = 0; this['i'] < n; this['i']++);
return this['i'];
}

--- case 1
strangerIdentity(100);
-> 100
i
-> 100

--- case 2
var id = new strangerIdentity(100);

id
-> strangerIdentity {i: 100}
id.i
-> 100
i
-> Uncaught ReferenceError: i is not defined

在Javascript中,只有一个Function才会产生新的作用域。直接调用一个funcation,其内部的指针指向global对象。但当使用new后,其作用域绑定到一个Function Object上。