今天看了js的作用域的知识,感觉收益匪浅,首先对于js的作用域,在程序执行的时候,有一句话一定要理解那就是

js函数运行在他定义时的作用域,而不是他们被执行的作用域里。

这句话一定要理解,下面来看个例子

function factory(){
var name = "laruence";
var intro = function ()
alert("I am "+name);
}
return intro;
}
function app (para)
var name = para;
var func = factory();
func();
}
app("eve");

然后我们来看看作用域链,当调用app的时候,scope chain是由{window活动全局对象}-》{app的活动对象}组成。
在刚进入app函数的函数体的时候,app活动对象有一个arguments属性,两个值为undefined属性:name和func和一个值为“eve”的属性para,此时的scope chain如下:

[[scope chain]] = [
{
para : 'eve',
name : undefined,
func : undefined,
arguments : []
}, {
window call object
}
]

当进入factory的函数体的时候。此时sfactory的scope chain为

[[scope chain]]

注意到,此时的作用域链并不包含app的活动对象,在定义intro函数的时候,intro函数的scope chain为

[[scope chain]] = [
{
name : 'laruence',
intor : undefined
}, {
window call object
}
]

从factory函数返回之后,在app体内调用了intor的时候,发生了标识符解析,scope chain为

[[scope chain]] = [
{
intro call object
}, {
name : 'laruence',
intor : undefined
}, {
window call object
}
]

因为scope chain中并不包含factory对象,所以name属性包含的是factory中活动的name属性,也就是’laruence’.

I

现在大家对函数是运行在定义时的作用域,而不是运行他们被执行的作用域里应该有个全面的了解。

js里的预编译

js里面其实是有一个预编译的过程的,这里有两个要点:
1.声明式的函数会被预编译。
看下面这个例子:

<script>typeof eve); //function
function eve()
alert('I am Laruence');
};
</script>

alert出来是有值的

<script>typeof eve); //结果:function
alert(typeof walle); //结果:undefined
function eve() //函数定义式
alert('I am Laruence');
};
var walle = function() //函数表达式
}
alert(typeof walle); //结果:function</script>

看这个walle就是未定义的。
2.函数是分块进行编译,但是共享变量等。
看这个例子:

<script>typeof eve); //结果:undefined</script>
<script>function eve()
alert('I am Laruence');
}
</script>