Ric*_*ico 5 javascript precompile
var foo=1;
function bar(){
foo=10;
return;
function foo(){}
}
bar();
alert(foo);Run Code Online (Sandbox Code Playgroud)
我目前正在学习javascript如何在机器中实际运行,这是我在示例中看到的一段代码.我不知道为什么最终警报是1而不是10.所以我想知道任何人都可以帮我解释javascript虚拟机是如何实际执行这些代码的.谢谢!
这是由于功能声明提升:
var foo=1;
function bar(){
function foo(){} // This gets moved up here by the engine
foo=10; // You've reassigned the local `foo` function to 10,
// leaving the global `foo` untouched
return;
}
bar();
alert(foo); // Since the foo has never changed in this scope, it's still 1
Run Code Online (Sandbox Code Playgroud)
\n\n\n我不知道为什么最终警报是 1 而不是 10。
\n
因为foo在这一行中bar:
foo = 10;\nRun Code Online (Sandbox Code Playgroud)\n\n...是稍后在该函数中由函数声明声明的类似变量的东西*:
\n\nfunction foo(){}\nRun Code Online (Sandbox Code Playgroud)\n\n...不是外面foo的bar。那是:
var foo=1;\nfunction bar(){\n foo=10; // <== This `foo`\n return;\n function foo(){} // <== Is the `foo` declared here\n}\nbar();\nalert(foo);\nRun Code Online (Sandbox Code Playgroud)\n\n...不是foo在包含范围 ( var foo) 中声明的。
发生这种情况有两个原因:
\n\nbar在函数中的任何逐步代码之前,函数声明在进入包含范围(在本例中是对 的调用)时立即进行处理。这有时称为“提升”声明(因为它们就像位于最顶层一样发生)。而且由于函数声明不是逐步代码,因此对其return是否被处理没有影响;它会在事情return发生之前得到处理。
函数声明还创建可能是带有函数名称的变量。因此,foo函数声明中的 有效地成为具有该名称的变量(更多内容见下文)——正如您在该代码中所看到的,您可以为这些“变量”分配新值。
当您运行该代码时,JavaScript 引擎执行的操作顺序如下:
\n\n创建一个名为 的变量foo并为其赋予初始值undefined。
创建 function bar,将bar其作为作用域内符号(实际上是变量)添加到当前作用域中,并使其成为对该bar函数的引用。
启动该范围的分步代码。
1将值赋给foo.
调用函数bar。
创建foo与调用相关的函数bar,foo在调用期间添加为作用域内符号(实际上是变量)并使其成为对该函数的引用。
启动该范围的分步代码。
将值分配10给本地foo(用于引用函数)。
从函数中返回。
alert在该范围内使用进行调用foo,该范围仍然具有值1。
您可以在规范的 \xc2\xa710.4.3及其链接到的部分中阅读所有血腥细节。
\n\n* “类似变量的东西” 在 JavaScript 中,每个执行上下文(全局上下文和通过调用函数创建的任何上下文等)都有一个对象,用于保存该上下文中使用的各种名称及其值;它被称为“绑定对象”。上下文的绑定对象(我在这里跳过一些不相关的细节)具有每个变量的属性、函数声明以及其他一些东西,例如arguments伪数组、函数本身的名称(返回函数) ,等等。属性的名称是变量、声明的函数等的名称。这就是为什么分配给fooinside会覆盖对在 中声明的函数的bar引用,而不是分配给外部作用域中的变量。实际上是中的局部变量,即使由于函数声明而未使用 进行声明。foobarfoobarvar
| 归档时间: |
|
| 查看次数: |
65 次 |
| 最近记录: |