声明前置
- 变量的声明前置:指在变量被定义时,会在代码执行之前将变量放在最前面进行初始化。
- 函数的声明前置:会将函数声明放在代码执行之前先去生成该函数,所以函数声明受到函数提升机制的影响,所以无论放在什么位置都可以被调用。
作用域
- 每当声明一个新的函数就进入一个新的作用域下;
- 函数里需要用到的变量(或函数)首先会在自身作用域下找,找不到再逐级向上层作用域去找。
作用域链查找过程伪代码
- 分析代码,首先可根据提升机制将变量或者函数编译在最前面;
- 写出作用域链查找过程伪代码,找到每个作用域的
AO
、Scope
;
- 根据伪代码方可分析出具体结果。
举例说明
- 变量的声明前置
console.log(a);//undefined
var a = 1;
console.log(a);//1
/* 声明前置分析代码 */
var a
console.log(a)//undefined
a = 1
console.log(a)
//变量a会声明前置,故第一次输出:undefined
//第二次输出前变量a已经赋值,故第二次输出:1
- 函数声明放在任何位置都会函数声明前置,而函数表达式只有在这个表达式执行完后才会调用改函数
sayName('world');
sayAge(10);
function sayName(name){
console.log('hello ', name);
}
var sayAge = function(age){
console.log(age);
};
/* 首先还是根据函数提升机制分析代码 */
function sayName(){...}
var sayAge
sayName('world') //输出:hello world
sayAge(10) //输出:sayAge is not a function
sayAge = function(){..}
-
var x = 10
bar()
function foo() {
console.log(x)
}
function bar(){
var x = 30
foo()
}
/* 首先根据声明前置分析代码 */
var x
function foo(){
console.log(x)
}
function bar(){
var x
x = 30
foo()
}
x = 10
bar()
/* 作用域链查找过程伪代码 */
globalContext{
AO:{
x:10
foo:function
bar:function
}
Scope:{}
}
foo[[scope]] = globalContext.AO
bar[[scope]] = globalContext.AO
fooContext{
AO:{}
Scope:foo[[scope]] = globalContext.AO
}
barContext{
AO:{
x:30
}
Scope:bar[[scope]] = globalContext.AO
}
//输出: 10
-
var x = 10;
bar()
function bar(){
var x = 30;
function foo(){
console.log(x)
}
foo();
}
/* 作用域链查找过程伪代码 */
globalContext{
AO:{
x:10,
bar:function
},
Scope:{}
}
bar[[scope]] = globalContext.AO
barContext{
AO:{
x:30,
foo:function
}
scope:bar[[scope]] = globalContext.AO
}
foo[[scope]] = barContext.AO
fooContext{
AO:{}
scope:barContext.AO
}
//输出:30
-
var a = 1;
function fn(){
console.log(a)
var a = 5
console.log(a)
a++
var a
fn3()
fn2()
console.log(a)
function fn2(){
console.log(a)
a = 20
}
}
function fn3(){
console.log(a)
a = 200
}
fn()
console.log(a)
/* 作用域链查找过程伪代码 */
globalContext{
AO:{
a:1->200
fn:function,
fn3:function
},
Scope:{}
}
fn[[scope]] = globalContext.AO
fn3[[scope]] = globalContext.AO
fnContext{
AO:{
a:5->6->20
fn2:function
}
scope:globalContext.AO
}
fn2[[scope]] = fnContext.AO
fn3Context{
AO:{}
scope:globalContext.AO
}
fn2Context{
AO:{}
scope:fnContext.AO
}
//输出: undefined 5 1 6 20 200
网友评论