如何在Javascript中使用带有函数表达式的变量提升?
How to use variable hoisting with function expression in Javascript?
我理解变量提升是将声明移动到函数或全局上下文顶部的行为。
这显示在下面的代码中:
console.log(a);
var a = 'Hello World!';
以上代码实际得到以下行为:
var a;
console.log(a);
a = 'Hello World!';
以上代码的结果输出是undefined
。
在上面的例子中,重要的是要注意变量提升只移动顶部的声明部分。初始化部分没有移到最上面
当我尝试使用函数表达式复制相同的行为时,我得到了意外的输出。
如下代码所示:
function sayHello() {
var say = function() { console.log(hello); }
var hello= 'Hello World !!';
return say;
}
sayHello()(); // output Hello World !!
我试图理解为什么我们没有收到 undefined
作为输出,因为变量 hello
仅在使用后才被初始化(类似于前面的示例)。
您看到的行为来自闭包的工作方式。并不是 hello
的值以某种方式被提升,而是读取 hello
值的代码(console.log(hello)
部分)仅在您设置值后执行!
为了避免与提升混淆,因为这与您所看到的并不真正相关,让我们按照提升后的方式编写代码:
function sayHello() {
var hello;
var say = function() { console.log(hello); }
hello = 'Hello World !!';
return say;
}
sayHello()(); // output Hello World !!
如果您要在行 hello = 'Hello World !!';
之前插入 say()
,它将打印 undefined
.
现在,当您有这样的代码时...
var hello;
var say = function() { console.log(hello); }
...那么 say
里面的 hello
不是外面 hello
的副本,它实际上是你在这里引用的同一个变量。即使在外部函数返回后它仍然存在,因为现在您有对 say
函数的引用,而该函数又仍然保留对 hello
.
的引用
I am trying to understand why we have not received undefined
as an output because the variable hello
is initialized only after it is used (similar to the previous example).
我想这是你的误会。当您在最后调用 say
函数时使用它 - 按时间顺序来说。从上到下看代码 hello
之前看起来是 "used" 并不重要,因为那不是代码执行的顺序。在 var say = function () { console.log(hello); }
行,您只需执行 var say = something;
,something
在那一点上没有任何意义(它只需要语法正确)。只有在最后调用 say
时才会访问 hello
。
(您也可以尝试使用类似 var say = function () { derp(); }
的方法,您会注意到只有在调用该函数时才会出现错误 derp is not defined
,而不会在您定义它时出现。)
所以,按时间顺序,是这样的:
sayHello
被称为
hello
已创建并包含 undefined
say
被创建并分配了一个主体为 console.log(hello)
的函数表达式
hello
已分配 "Hello World !!"
sayHello
returns say
- 函数表达式(
say
)被调用
console.log(hello)
执行
- 请记住
hello
包含 "Hello World !!"
在这一点上
- 字符串
"Hello World !!"
被打印出来
你可以扩展这个例子,帮助理解:
function sayHello() {
var hello;
var say = function() { console.log(hello); }
hello = 'Hello World !!';
var think = function() { hello = 'What should I think about?'; }
return [say, think];
}
var [say, think] = sayHello();
say(); // Prints "Hello World !!";
think();
say(); // prints "What should I think about?"
如您所见,hello
继续存在并可供 say
和 think
使用,即使在 sayHello
返回后,所有这些部分代码引用相同的 hello
变量。
我理解变量提升是将声明移动到函数或全局上下文顶部的行为。 这显示在下面的代码中:
console.log(a);
var a = 'Hello World!';
以上代码实际得到以下行为:
var a;
console.log(a);
a = 'Hello World!';
以上代码的结果输出是undefined
。
在上面的例子中,重要的是要注意变量提升只移动顶部的声明部分。初始化部分没有移到最上面
当我尝试使用函数表达式复制相同的行为时,我得到了意外的输出。
如下代码所示:
function sayHello() {
var say = function() { console.log(hello); }
var hello= 'Hello World !!';
return say;
}
sayHello()(); // output Hello World !!
我试图理解为什么我们没有收到 undefined
作为输出,因为变量 hello
仅在使用后才被初始化(类似于前面的示例)。
您看到的行为来自闭包的工作方式。并不是 hello
的值以某种方式被提升,而是读取 hello
值的代码(console.log(hello)
部分)仅在您设置值后执行!
为了避免与提升混淆,因为这与您所看到的并不真正相关,让我们按照提升后的方式编写代码:
function sayHello() {
var hello;
var say = function() { console.log(hello); }
hello = 'Hello World !!';
return say;
}
sayHello()(); // output Hello World !!
如果您要在行 hello = 'Hello World !!';
之前插入 say()
,它将打印 undefined
.
现在,当您有这样的代码时...
var hello;
var say = function() { console.log(hello); }
...那么 say
里面的 hello
不是外面 hello
的副本,它实际上是你在这里引用的同一个变量。即使在外部函数返回后它仍然存在,因为现在您有对 say
函数的引用,而该函数又仍然保留对 hello
.
I am trying to understand why we have not received
undefined
as an output because the variablehello
is initialized only after it is used (similar to the previous example).
我想这是你的误会。当您在最后调用 say
函数时使用它 - 按时间顺序来说。从上到下看代码 hello
之前看起来是 "used" 并不重要,因为那不是代码执行的顺序。在 var say = function () { console.log(hello); }
行,您只需执行 var say = something;
,something
在那一点上没有任何意义(它只需要语法正确)。只有在最后调用 say
时才会访问 hello
。
(您也可以尝试使用类似 var say = function () { derp(); }
的方法,您会注意到只有在调用该函数时才会出现错误 derp is not defined
,而不会在您定义它时出现。)
所以,按时间顺序,是这样的:
sayHello
被称为hello
已创建并包含undefined
say
被创建并分配了一个主体为console.log(hello)
的函数表达式
hello
已分配"Hello World !!"
sayHello
returnssay
- 函数表达式(
say
)被调用 console.log(hello)
执行- 请记住
hello
包含"Hello World !!"
在这一点上
- 请记住
- 字符串
"Hello World !!"
被打印出来
你可以扩展这个例子,帮助理解:
function sayHello() {
var hello;
var say = function() { console.log(hello); }
hello = 'Hello World !!';
var think = function() { hello = 'What should I think about?'; }
return [say, think];
}
var [say, think] = sayHello();
say(); // Prints "Hello World !!";
think();
say(); // prints "What should I think about?"
如您所见,hello
继续存在并可供 say
和 think
使用,即使在 sayHello
返回后,所有这些部分代码引用相同的 hello
变量。