作用域链
2019-01-14 本文已影响0人
astak3
作用域链
作用域:就近原则
在写下声明就能确定的,叫做词法作用域
var a = 1
function bar(){
var a = 2
console.log(a) //2
}
词法作用域可以确定是哪个a
,但不能确定a
的值
var a
function foo(){
var a = 1
bar()
}
function bar(){
console.log(a) //100
}
a = 100
foo()
关于作用域链,浏览器内部究竟发生了什么:
例子1:
var x = 10
bar()
function foo() {
console.log(x) //10
}
function bar(){
var x = 30
foo()
}
1. 声明前置
globalContext = {
AO:{
x:10,
foo:function(){},
bar:function(){}
},
Scope:null
}
foo.[[scope]] = globalContext.AO
bar.[[scope]] = globalContext.AO
2. 调用 bar
barContext = {
AO:{
x:30
}
Scope:bar.[[scope]] = globalContext.AO
}
3. 调用 foo
fooContext = {
AO:{}
Scope:foo.[[scope]] = globalContext.AO
}
例子2:
var x = 10;
bar()
function bar(){
var x = 30;
function foo(){
console.log(x) //30
}
foo();
}
1. 声明前置
globalContext = {
AO:{
x:10
bar:function
}
Scope:null
}
bar.[[scope]] = globaleContext.AO
2. 调用 bar
barContext = {
AO:{
x:30
foo:function
}
Scope:bar.[[scope]] = globaleContext.AO
}
foo.[[scope]] = barContext.AO
3. 调用 foo
fooContext = {
AO:{}
Scope:foo.[[scope]] = barContext.AO
}
例子3:
var x = 10;
bar()
function bar(){
var x = 30;
(function (){
console.log(x) //30
})()
}
1. 声明前置
globalContext = {
AO:{
x:10
bar:function
}
Scope:null
}
bar.[[scope]] = globalContext.AO
2. 调用 bar
barContext = {
AO:{
x:30
function
}
Scope:bar.[[scope]] = globalContext.AO
}
function.[[scope]] = barContext.AO
3. 调用 function
functionContext = {
AO:{}
Scope:function.[[scope]] = barContext.AO
}
例子4:
var a = 1;
function fn(){
console.log(a) //1,undefined
var a = 5
console.log(a) //2,5
a++
var a
fn3()
fn2()
console.log(a) //5,20
function fn2(){
console.log(a) //4,6
a = 20
}
}
function fn3(){
console.log(a) //3,1
a = 200
}
fn()
console.log(a) //6,200
1. 声明前置
globalContext = {
AO:{
a:200
fn:function
fn3:function
}
Scope:null
}
fn.[[scope]] = globalContext.AO
fn3.[[scope]] = globalContext.AO
2. 调用 fn
fnContext = {
AO:{
a:20
fn2:funcion
}
Scope:fn.[[scope]] = globalContext.AO
}
fn2.[[scope]] = fnContext.AO
3. 调用 fn3
fn3Context = {
AO:{}
Scope:fn3.[[scope]] = globalContext.AO
}
4. 调用 fn2
fn2Context = {
AO:{}
Scope:fn2.[[scope]] = fnContext.AO
}