javascript拾遗(2)

”JavaScript中的函数运行在它们被定义的作用域里,而不是它们被执行的作用域里.”

全局作用域(Global Scope)

最外层函数和变量

在代码中任何地方都能访问到的对象拥有全局作用域

window对象的属性拥有全局作用域


vara=10;// 全局

(function(){

     var b=20;// 函数

})();

console.log(a);// 10

console.log(b);// error, b in not defined

eval("var a = 1;");// eval


作用域链(Scope Chain)

在 JavaScript 中,函数也是对象,实际上,JavaScript里一切都是对象

作用域的实现却和C/C++不同,并非用“堆栈”方式,而是使用列表,具体过程如下(ECMA262中所述):

任何执行上下文时刻的作用域, 都是由作用域链(scope chain, 后面介绍)来实现.

在一个函数被定义的时候, 会将它定义时刻的scope chain链接到这个函数对象的[[scope]]属性.

在一个函数对象被调用的时候,会创建一个活动对象(也就是一个对象), 然后对于每一个函数的形参,都命名为该活动对象的命名属性, 然后将这个活动对象做为此时的作用域链(scope chain)最前端, 并将这个函数对象的[[scope]]加入到scope chain中.

eg: 在调用func的时候, 会创建一个活动对象(假设为aObj, 由JS引擎预编译时刻创建, 后面会介绍),并创建arguments属性,

然后会给这个对象添加俩个命名属性aObj.lps, aObj.rps; 对于每一个在这个函数中申明的局部变量和函数定义,

都作为该活动对象的同名命名属性.

然后将调用参数赋值给形参数,对于缺少的调用参数,赋值为undefined。


var name = 'laruence';

function echo() {    

 alert(name);     

var name = 'eve';    

 alert(name);     

alert(age);} 

echo();

undefined//alert定义时的作用域链+alert自己参数+函数内均无name

eve

[脚本出错]

延长作用域链

有些语句可以在作用域链的前端临时增加一个变量对象,该变量对象会在代码执行后被移除。有两种情况下会发生这种现象。

try-catch语句中的catch块

with语句


变量初始化阶段

JS解释器如何找到我们定义的函数和变量?

变量对象 (Variable Object, 缩写为VO) 是一个抽象概念中的“对象”,它用于存储执行上下文中的:

变量

函数声明

函数参数

VO按照如下顺序填充:

函数参数 (若未传入,初始化该参数值为undefined)

函数声明 (若发生命名冲突,会覆盖)

变量声明 (初始化变量值为 undefined,若发生命名冲突,会忽略。)

你可能感兴趣的:(javascript拾遗(2))