JS运行三部曲
1、语法分析
2、预编译
3、解析执行
预编译:
对于函数,执行上下文四部曲:
· 1、创建AO对象,
· 2、找到形参和变量声明,将变量和形参名作为AO属性名,值为undefined
· 3、将形参值和实参相统一
· 4、在函数体内找函数声明,将函数提升至最顶层(如果已有定义的相同的属性名,则完全替换这个属性)。
作用域(静态作用域)
作用域是指程序源代码中定义变量的区域。
JavaScript采用词法作用域,也就是静态作用域。所以函数的作用域在定义的时候就决定了。
看一个例子:
var value = 1;
function foo(){
console.log(value);
}
function bar(){
var value = 2;
foo();
}
bar(); // 1
静态作用域执行过程:
执行foo函数,先从foo函数内部查找是否有局部变量value,如果没有,就根据定义foo函数的位置,查找上面一层的代码,也就是value 等于1,所以会打印1。
动态作用域执行过程:
执行foo函数,先从foo函数内部查找是否有局部变量value,如果没有,就从调用函数的作用域,也就是 bar 函数内部查找 value,所以会打印2。
思考
var scope = 'global scope';
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f();
}
console.log(checkscope());
var scope = 'global scope';
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f;
}
console.log(checkscope()());
这两段代码都会打印:local scope。
因为JavaScript采用的是词法作用域,函数向上访问的作用域,基于函数创建的位置,而不是函数调用的位置。
作用域链
当一个块级作用域或函数嵌套在另一个块或函数中时,就发生了作用域嵌套。因此,在当前作用域中无法搜索到某个变量时,JS引擎就会向外层( 父级 )作用域中查找,直到搜索到该变量,或者抵达最外层作用域( 也就是全局作用域 ),形成了作用域链。
var scope = 'global';
function fun(){
var value = 12;
function fun1(){
var name = 'cyl'
console.log(name); // cyl
console.log(value); // 12
console.log(scope); // global
}
return fun1();
}
fun();
网友评论