AO = {
关于这个标题题目,NC搬出了262-3的规范出来解释,实在从《深入理解JavaScript系列(12):变量对象(Variable Object)》中的函数上下文中的变量对象一节就可以清晰地知道,流动对象是在进入函数上下文时刻被创建的,它通过函数的arguments属性初始化。arguments属性的值是Arguments对象:
b(1, 2, 3);
VO(global) = {
这个标题题目就是标题题目2里的大叔加的注释了,也就是函数声明和变量声明的关系和影响,碰到同名的函数声明,VO不会重新定义,所以这时候全局的VO应该是如下这样的:
alert(a);
function a(x) {
标题题目3
上述例子中,变量a在函数a后面,那么,变量a碰到函数a怎么办呢?仍是根据变量对象中先容的,当变量声名碰到VO中已经有同名的时候,不会影响已经存在的属性。而函数表达式不会影响VO的内容,所以b只有在执行的时候才会触发里面的内容。
进入执行上下文: 这里泛起了名字一样的情况,一个是函数声名,一个是变量声名。那么,根据深入理解JavaScript系列(12):变量对象(Variable Object)先容的,填充VO的顺序是: 函数的形参 -> 函数声名 -> 变量声名。
大叔注:安装ECMAScript规范,作者对函数声明笼盖变量声明的解释实在不正确的,准确的理解应该是如下:
这样的话,就很清楚地知道为什么alert的老是1了,具体内容请参考《深入理解JavaScript系列(2):揭秘命名函数表达式》中的内容。
alert(a);
var a = 1,
理解上述内容之后,该标题题目换成一个更正确和更轻易理解的代码应该像这样:
重新回到标题题目,这个函数实在是一个有名函数表达式,函数表达式不像函数声明一样可以笼盖变量声明,但你可以留意到,变量b是包含了该函数表达式,而该函数表达式的名字是a;不同的浏览器对a这个名词处理有点不一样,在IE里,会将a以为函数声明,所以它被变量初始化笼盖了,就是说假如调用a(--x)的话就会犯错,而其它浏览器在答应在函数内部调用a(--x),由于这时候a在函数外面依然是数字。基本上,IE里调用b(2)的时候会犯错,但其它浏览器则返回undefined。
该value赋值以后,变量赋值初始化就笼盖了函数声明。
alert(
typeof value);
//"number" function value(){
尽快变量声明在下面定义,但是变量value依然是function,也就是说这种情况下,函数声明的优先级高于变量声明的优先级,但假如该变量value赋值了,那结果就完全不一样了:
alert(
typeof value);
//"function" function value(){
第三需要知道的是,函数声明会笼盖变量声明,但不会笼盖变量赋值,为了解释这个,我们来看一个例子:
澄清一下,函数表达式没有提前,就相称于平时的变量赋值。
};
var functionName = function(arg1, arg2){
如下不是函数,而是函数表达式,相称于变量赋值:
} function functionName(arg1, arg2){
量声明一样。澄清一下,函数声明是如下这样的代码:
首先,在标题题目1里我们知道了变量声明在进入执行上下文就完成了;第二个概念就是函数声明也是提前的,所有的函数声明都在执行代码之前都已经完成了声明,和变
这个标题题目看起来比实际复杂,alert的结果是1;这里依然有3个重要的概念需要我们知道。
alert(a); var a = 1,
标题题目2
大叔注:相信良多人都是以为a在里面不可访问,结果才是undefined的吧,实在是已经有了,只不外初始值是undefined,而不是不可访问。
然后执行代码的时候才开始走if语句,具体信息请查看《深入理解JavaScript系列(12):变量对象(Variable Object)》中的处理上下文代码的2个阶段小节。
这个时候a已经有了;
} VO(global) = {
大叔注:提前这个词语显得有点疑惑了,实在就是执行上下文的关系,由于执行上下文分2个阶段:进入执行上下文和执行代码,在进入执行上下文的时候,创建变量对象VO里已经有了:函数的所有形参、所有的函数声明、所有的变量声明
这样,标题题目的意思就非常清晰了:首先声明a,然后判定a是否在存在,假如不存在就赋值为1,很显著a永远在window里存在,这个赋值语句永远不会执行,所以结果是undefined。
alert(a); var a;
所以,知道了这些概念以后,重新回头看一下标题题目的代码,实在就等价于:
当变量声明和赋值在一起用的时候,JavaScript引擎会自动将它分为两部以便将变量声明提前,不将赋值的步骤提前是由于他有可能影响代码执行出不可预期的结果。
a = 1; //初始化赋值 var a; //声明
你可以将语句拆分为如下代码:
第三,你需要理解该标题题目的意思是,变量声明被提前了,但变量赋值没有,由于这行代码包括了变量声明和变量赋值。
这样看起来就很轻易解释为什么alert结果是true了。
alert("a" in window); var a;
此时,尽管声明是在alert之后,alert弹出的依然是true,这是由于JavaScript引擎首先会扫墓所有的变量声明,然后将这些变量声明移动到顶部,终极的代码效果是这样的:
var a; alert("a" in window);
第二,所有的变量声明都在范围作用域的顶部,看一下相似的例子:
首先,所有的全局变量都是window的属性,语句 var a = 1;等价于window.a = 1; 你可以用如下方式来检测全局变量是否声明:
你可能以为alert出来的结果是1,然后实际结果是“undefined”。要了解为什么,我们需要知道JavaScript里的3个概念。
代码看起来是想说:假如window不包含属性a,就声明一个变量a,然后赋值为1。
alert(a);