`
hastune
  • 浏览: 4399 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

【qw群沉淀】函数声明、形参、变量声明优先级

阅读更多
Franky 11:13:16
附上我的 笔记:


变量实例化(Variable Instantiation):(初始化执行上下文环境阶段)
     每个执行环境都有一个相关联的变量对象(variable object).用来维护变量和函数的声明的标识符. 他们被当做变量对象的属性(property),添加到该对象上. 对于函数执行环境来说,形式参数也同变量声明一样被当做属性,添加到该对象上.
     什么对象被当做变量对象来使用,以及该对象相关属性具备哪些特性.是由可执行代码的类型决定的.
          .对于函数代码(function code) :
               对于每个形参来说,同样会在变量对象上创建一个属性名与形参名(标识符)相同的属性. 这些属性的特性同样由代码类型决定. 这些参数的值由函数调用者提供.
               如果函数调用者,提供的实参数量少于形参数量,余下的形参的值就是undefined.
               如果有两个或多个形参同名,则由最后一个使用此名的形参对应的实参,向变量对象对应属性提供值,如果无对应实参,则对应属性值为undefined.(即该形参的值为undefined).

          .对于代码中的每个函数声明(FunctionDeclaration)语句来说 :
               按照源码文本的顺序,以函数标识符(函数名)作为属性名,来建立对应变量对象的属.性.并把同时创建的函数对象作为该属性的值. 这些属性的特性由代码类型决定.
               如果变量对象已经具备一个同名的属性,则覆盖掉原来的.
               出于语义化的考量, 这个步骤必须在形式参数列表对象(本意应该是指,对应形参标识符的 变量对象的属性创建过程)创建之后. (注1)


          .对于代码中的每个变量声明语句,或语句中不包含 in 运算符的变量声明来说For each VariableDeclaration or VariableDeclarationNoIn in the code)(注2)
               根据变量标识符(变量名) ,为变量对象创建对应的属性.属性值为 undefined. 这些属性的特性由代码的类型决定.
               如果变量对象已经具备一个同变量标识符同名的属性,则该属性不做任何改变.包括特性.
     所以,如果一个声明的变量名和一个函数名或者形参重名,那么这个变量的声明并不影响变量对象已经存在的对应属性以及该属性的特性.(这一点和函数名相反.)
     (即特指函数声明和形参的优先级,高于变量声明 . 根据,函数声明语句的说明,我们得出 函数声明 > 形参 > 变量声明的结论)

Franky 11:16:02
注1 . Edition5中,对标识符初始化的过程描述,细节上虽然有很大差异.但最终的流程却是统一的, 即 先做形参初始化(包括arguments的初始化), 然后是函数声明,最后才是变量声明. 优先级也雷同.
        所谓语义化的考量. 即如下情况:
       
 void function(fn){
               function fn(){};
               alert(typeof fn)// function.
          }();

       即,考虑开发者对函数形参和函数声明语句中的标识符的期待. 这种期待是一种语义上的诉求. 即函数声明.具备最高优先级.
           
       但是下面的代码,会很让人诧异:
      
          function test(fn){
               function fn(){}
               alert(fn );
          }
          test(123);


     测试结果:
          Firefox1.5-   打印 123
其他浏览器  打印 fn函数的字符串表示
   
     仅仅参考这里是无法知道 什么叫做,函数名的初始化过程要在 参数列表对象创建之后. 参考  13.2.1章节 的函数调用的具体步骤可看出:
         1.  Establish a new execution context using F's FormalParameterList, the passed arguments list, and the this value as described in 10.2.3
         2.  Evaluate F's FunctionBody.
      第一步就是创建新的执行环境,并使用该函数被调用时候,调用者提供的参数列表创建形参列表. 然后第二部才是执行函数体内的语句.所以说,局部函数声明,的初始化过程要在形参初始化之后.而形参初始化时,其对应的实参值,就已经被相应的写入到variable object上去了. 所以函数声明时,会覆盖掉形参,而不是形参对应的实参会覆盖函数声明.

          那么我们可以看出,早期的Firefox对标准理解有错误.其他浏览器都是OK的

注2 . ExpressionNoIn ....etc  都是指语句、或表达式 中不包含 in 运算符的形式. 在注释2中的 VariableDeclarationNoIn 特指 如 for (var o in obj)   语句中 ,var o in obj部分 就属于一个 非NoIn的变量声明表达式..
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics