第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
分享到:
相关推荐
在JavaScript中,同名的函数和变量在执行时遵循不同的规则,而这些规则往往会影响到代码的执行顺序和最终的行为表现。首先,我们来看看同名函数的情况。 在JavaScript中,如果在一个作用域内定义了两个或多个同名的...
另一方面,对于另一些基本偏差代号(如JS、js、S、s),与基准轴形成配合时,则必须在相配孔、轴的精度等级相同的情况下才能保证同名配合性质相同。 #### 分界点或转折点的概念 在基轴制配合中,当相配孔的基本...
本文详细介绍了如何使用MSXML来解析XML文档中的同名节点。主要讨论了如何使用`getElementsByTagName()`方法获取同名节点列表,如何遍历这些节点以及如何获取节点的属性。通过这些方法,开发者可以灵活地处理XML数据...
随着项目的不断增大,路由配置的复杂性也会相应增加,这时就可能会遇到路由配置中name属性同名以及路由重复的问题。这个问题会使得路由系统无法正确匹配到目标路由,从而影响到项目的正常运行。 首先,我们来分析...
在实际项目中,将这些功能封装到独立的JS文件中可以提高代码的可维护性和重用性。 总的来说,通过jQuery,我们可以方便地创建和管理同名的input输入框,满足动态表单的需求。结合HTML、CSS和JavaScript,可以构建出...
经过查找资料和测试发现如果在打开窗体的时候指定的窗体名和当前的某个窗体同名的时候就会在那个窗体上打开。例如下面的情况: window.open(“view_svg.jsp?ukey=<%=ukey%>&itemID=<%=itemID%>&...
在这个例子中,可能有一个Vue实例,其中包含同名人信息的数据,这些数据的变化会自动反映在视图上,反之亦然。 3. 组件化:Vue.js 提倡组件化的开发方式,将UI拆分成可复用的模块。在这个项目中,可能存在一个或多...
本文将深入分析JavaScript函数参数传递的原理,探讨同名参数在函数中的表现,并通过实例分析来帮助大家更好地理解和应用这些概念。 首先,我们需要明确JavaScript中参数传递的两种基本类型:值传递和引用传递。当...
同名标识符优先级指的是在不同作用域中存在相同名称的标识符时,JavaScript引擎如何决定使用哪一个标识符。这涉及到变量作用域、提升(hoisting)、参数传递、函数声明、函数表达式等方面的知识点。 首先,关于局部...
JavaScript是Web开发中不可或缺的一部分,尤其在前端领域,它提供了丰富的功能来创建动态和交互性的网页。在JavaScript中,对象继承是实现面向对象编程(OOP)的关键特性之一。对象继承允许一个对象(子对象)从另一...
在编程领域,Python、JavaScript、Java等语言都有强大的文件操作库,可以方便地实现批量处理任务。例如,Python的`os`和`shutil`模块提供了丰富的文件操作函数,而`os.rename()`用于重命名,`os.chmod()`用于修改...
3. **外部脚本**:将JavaScript代码放在单独的`.js`文件中,再通过`<script>`标签引入到HTML文档中。 ```html <script type="text/javascript" src="js/script.js"> ``` 注意:当`<script>`标签用于引入外部文件...
13. **同名函数覆盖**:JavaScript中,后定义的同名函数会覆盖前面的,所以`add(10)`将输出20,选项C正确。 14. **对象与方法**:在JavaScript中,对象的方法可以在实例化后添加。给定代码中,`student`对象被创建...
今天骚凯问了一道变量名冲突的题目,感觉很有意思,顺便也复习一下...4)变量和赋值语句一起书写,在js引擎解析时,会将其拆成声明和赋值2部分,声明置顶,赋值保留在原来位置 5)声明过的变量不会重复声明 知道以上的规
标题“无限制弹出窗口(JS)”指的是在网页中利用JavaScript实现的一种技术,它允许开发者创建无限数量或在用户浏览过程中持续出现的弹出窗口。这种技术可能会被滥用,导致用户体验下降,甚至被认为是恶意行为,如广告...
在 JavaScript 中,函数体内部的局部变量的优先级比同名的全局变量高。这是因为 JavaScript 会优先查找当前作用域中的变量,而不是全局变量。 JavaScript 还没有块级作用域,这意味着在 if 语句、for 循环、while ...