JavaScript是否重新创建返回后的函数
以下代码:JavaScript是否重新创建返回后的函数,javascript,Javascript,以下代码: a = function(b) { return alfa() + b; function alfa() { return 7; } } console.log(a(4)); console.log(a(5)); 函数alfa()是否在每次调用a()时创建?是的,它将创建 函数声明和由var声明的变量都是在函数调用时挂起的。这意味着,无论在函数上下文中的何处声明函数声明,从技术上讲,它都是预先声明的 a = function(b) {
a = function(b) {
return alfa() + b;
function alfa() {
return 7;
}
}
console.log(a(4));
console.log(a(5));
函数alfa()是否在每次调用a()时创建?是的,它将创建
函数声明和由var
声明的变量都是在函数调用时挂起的。这意味着,无论在函数上下文中的何处声明函数声明,从技术上讲,它都是预先声明的
a = function(b) {
return alfa() + b;
function alfa() {
return 7;
}
}
从技术上讲,将成为
a = function(b) {
function alfa() {
return 7;
}
return alfa() + b;
}
函数alfa()是否在每次调用a()时创建
每次都会创建一个新的函数对象,是的,并绑定到不同的执行上下文(因此它可以访问b
的值,该值在创建时被传递到A
;alfa
是对创建它的A
调用上下文的“闭包”)
智能JavaScript引擎(如V8)可以很好地重用底层代码,但每次都会创建不同的对象。是的,它会。每次调用
a
,都会创建alfa
的新实例
顺便说一下,在这种情况下,alfa
关闭a
上下文。这就是我们所说的闭包,它允许我们在不同调用之间保持函数的状态。是
您使用的语法是sugar:
a = function(b) {
var alfa = function() {
return 7;
}
return alfa() + b;
}
console.log(a(4));
console.log(a(5));
它使每次执行a
时创建和分配alfa
更加清晰
您还可以使用以下简单更改对其进行测试:
a = function(b) {
return alfa; // let's return the function
function alfa() {
return 7;
}
}
console.log(a(4)==a(4)); // logs false
如果要避免每次创建alfa
,可以执行以下操作:
a = (function(){
var alfa = function() {
return 7;
}
return function(b) {
return alfa() + b;
}
})();
这个问题与吊装无关。@T.J.Crowder:我不确定。关于函数初始化的最后一个问题,差不多有。你的意思是“函数alfa()是在每次调用a()时创建的吗?”*这与提升有什么关系?我不明白你的意思。在我看来,整个问题就像OP对
return
语句和后面的函数声明感到困惑一样。这个问题怎么可能不是围绕着这样的问题呢?哇,我们只是完全不同地阅读了“函数是在每次调用a()时创建的吗?”。我看不到类似“为什么我可以在定义之前调用alfa
”,我看到“…每次调用a()”时,只看到事物的顺序为零。但是不用担心。除了在计算机编程中,alpha()
只运行一次,然后被销毁。@T.J.Crowder范围是计算机程序中的上下文,其中变量名或其他标识符是有效的,可以使用
@FlorianMargaine:对。闭包与作用域无关,它们与对a
的调用所创建的执行上下文的访问有关。作用域是关于符号分辨率的。换句话说:对a
的所有调用都有相同的作用域(一组可用的变量名),但对a
的每个调用都有自己的执行上下文(这些变量的特定实例),这使得闭包非常有用。(顺便说一句,如果你要引用某个东西,你不应该引用它吗?或者如果它是原文,为什么要让它看起来像引用?)@Jack:是的,但理论上它在存在的短暂时间内仍然是一个终结。(在现实世界中,它可能永远不存在,因为任何半正常的引擎都会将其内联,但是…)。它实际上更多的是对所有父上下文激活对象的词法查找,分别是词法环境记录,它们都存储在执行上下文中。“语法糖”意味着您有另一种相同效果的语法。您的示例没有相同的效果,因此不是语法上的甜点。但这是一个很好的类比:P@FlorianMargaine为什么它没有同样的效果?@FlorianMargaine是对的。在这种情况下,将声明一个新变量,该变量将函数表达式指定为引用。这里我们不再讨论函数声明。我并不是说这会在运行时改变任何事情,但它仍然是一个很大的区别。