js中同名心的


第1节:
ECMAScript 5th中,函数执行的处理顺序(简要说明,详细的见帖后的原文)
首先进行执行环境的创建{
  先进行形参声明及赋值
  再进行函数声明及赋值
  如果arguments在当前环境未声明,则声明并初始化。否则不作处理
  最后进行函数体内的变量声明
}
然后才是执行函数体语句
例如代码中的var a = 1,在函数执行前就处理了a的声明,执行时只是赋值a=1而已

再分析你写的示例:
第2节:
Js代码
function fn(fn){  
    alert(fn);  
}  
fn('hello'); // --> "hello" 

function fn(fn){
alert(fn);
}
fn('hello'); // --> "hello"

首先,这段代码运行前会先处理函数声明,在全局创建了fn这个变量。
然后执行函数体:fn('hello'),这时进入新的函数,先创建执行环境:
声明形参fn,值为'hello'
然后执行函数体:alert(fn)
对于标识符(identifier)的取值,先从当前环境查找,找到了'hello'。
(如果没找到,往上层环境查找,那就是函数定义时的环境了,即全局,它也有fn。参考scope chain)

第4节:
Js代码
function fn(a){  
    var a;  
    alert(a);  
}  
fn('hello'); // --> "hello" 

function fn(a){
var a;
alert(a);
}
fn('hello'); // --> "hello"

fn调用时创建执行环境:
声明形参a,值为'hello'
处理变量声明,a已经声明,不作处理
(处理函数体内变量声明时,如果已经声明过,不作处理。未声明时才声明并设置为undefined)

第5节:
Js代码
function fn(a){  
    var a = 1;  
    alert(a);  
}  
fn('hello'); // --> "1" 

function fn(a){
var a = 1;
alert(a);
}
fn('hello'); // --> "1"

执行环境建立:
(同第4节)
声明形参a,值为'hello'
处理变量声明,a已经声明,不作处理
执行函数体:
a = 1  // 修改变量a的值为1
...
(没什么优先级,a = 1这一句的a,还是参数声明时创建的标识符。同4节,函数体内变量重复声明不作任何处理)

第6节:
Js代码
function fn(a){  
    var a = a;  
    alert(a);  
}  
fn('hello'); 

function fn(a){
var a = a;
alert(a);
}
fn('hello');

执行环境建立:
(同第4,5节)
声明形参a,值为'hello'
处理变量声明,a已经声明,不作处理
执行函数体:
a = a  // 变量a的值不变,还是为hello
...


附1
ECMAScript 5th中的声明绑定过程(Declaration Binding Instantiation)及部分翻译(个人理解,译得不准请见谅):

引用

10.5  Declaration Binding Instantiation
Every execution context has an associated VariableEnvironment. Variables and functions declared in ECMAScript code evaluated in an execution context are added as bindings in that VariableEnvironment’s Environment Record. For function code, parameters are also added as bindings to that Environment Record.
Which Environment Record is used to bind a declaration and its kind depends upon the type of ECMAScript code executed by the execution context, but the remainder of the behaviour is generic. On entering an execution context, bindings are created in the VariableEnvironment as follows using the caller provided code and, if it is function code, argument List args: // 设args为实参数组

1.  Let env be the environment record component of the running execution context’s VariableEnvironment.
2.  If code is eval code, then let configurableBindings be true else let configurableBindings be false.
3.  If code is strict mode code, then let strict be true else let strict be false.
4.  If code is function code, then 
a.  Let func be the function whose [[Call]] internal method initiated execution of code. Let names be the value of func’s [[FormalParameters]] internal property.   // 设func为函数,names为形参数组
b.  Let argCount be the number of elements in args. // 设argCount为实参个数
c.  Let n be the number 0. // 设n为0
d.  For each String argName in names, in list order do // 顺序遍历形参数组,对每个形参名argName作处理
i.  Let n be the current value of n plus 1. // n=n+1 (即n为当前形参序号,从1开始)
ii.  If n is greater than argCount, let v be undefined otherwise let v be the value of the n’th element of args. // 如果n大于形参数目,则设v为undefined。否则v为对应的实参值
iii.  Let argAlreadyDeclared be the result of calling env’s HasBinding concrete method passing argName as the argument. // 设argAlreadyDeclared为[当前环境.标识符是否已声明(argName)]的返回值
iv.  If argAlreadyDeclared is false, call env’s CreateMutableBinding concrete method passing argName as the argument. // 如果为false,即未声明,则创建之
v.  Call env’s SetMutableBinding concrete method passing argName, v, and strict as the arguments. // 设置环境中的argName变量值为v
5.  For each FunctionDeclaration f in code, in source text order do // 对于函数声明,按代码先后作处理(对于函数声明详细信息,见附2)
a.  Let fn be the Identifier in FunctionDeclaration f.
b.  Let fo be the result of instantiating FunctionDeclaration f as described in Clause 13.
c.  Let funcAlreadyDeclared be the result of calling env’s HasBinding concrete method passing fn as the argument.
d.  If funcAlreadyDeclared is false, call env’s CreateMutableBinding concrete method passing fn and configurableBindings as the arguments. // 如果标识符未声明,则声明之
e.  Call env’s SetMutableBinding concrete method passing fn, fo, and strict as the arguments. // 设置值
6.  Let argumentsAlreadyDeclared be the result of calling env’s HasBinding concrete method passing "arguments" as the argument  // 设argumentsAlreadyDeclared为[当前环境.标识符是否已声明("arguments")]的返回值
7.  If code is function code and argumentsAlreadyDeclared is false, then // 如果未声明,则处理
a.  Let argsObj be the result of calling the abstract operation CreateArgumentsObject (10.6) passing  func, names, args, env and strict as arguments.
b.  If strict is true, then 
i.  Call env’s CreateImmutableBinding concrete method passing the String "arguments" as the argument.
ii.  Call env’s InitializeImmutableBinding concrete method passing "arguments" and argsObj as arguments.
c.  Else,
i.  Call env’s CreateMutableBinding concrete method passing the String "arguments" as the argument.
ii.  Call env’s SetMutableBinding concrete method passing "arguments", argsObj, and false as arguments.
8.  For each VariableDeclaration and VariableDeclarationNoIn d in code, in source text order do // 按代码顺序处理变量声明
a.  Let dn be the Identifier in d.
b.  Let varAlreadyDeclared be the result of calling env’s HasBinding concrete method passing dn as the argument.
c.  If varAlreadyDeclared is false, then // 如果未声明
i.  Call env’s CreateMutableBinding concrete method passing dn and configurableBindings as the arguments. // 声明标识
ii.  Call env’s SetMutableBinding concrete method passing dn, undefined, and strict as the arguments. // 设值为undefined



你可能感兴趣的:(C++,c,F#,C#)