在javascript';创建阶段';?
我现在正在学习Udemy课程,我刚刚了解了解释器解释JS时发生的创建阶段和执行阶段 我有一个问题,但我将首先向您展示我正在使用的代码: 如果我理解正确,在创建阶段,变量和函数是“设置”的,这意味着它们在内存中被指定了点。变量都被赋予了未定义的占位符值。然后在执行阶段,引擎执行从顶部开始的行。当第一次调用b()时,“a”仍然具有未定义的占位符值,然后将“a”的初始值指定为“peas”,再次调用b(),这次“a”的值为“peas”。 在我看来,这里必须发生两件事中的一件。备选方案1:在创建阶段,所有变量都在函数之前设置。这意味着,当为函数b()创建内存空间时,该函数包含a的值undefined(因为已使用值undefined创建了“a”内存空间)。备选方案2:函数和变量按照它们所处的词法顺序设置(在本例中,b是在a之前创建的),当b被创建时,“a”引用以某种方式表示函数正在侦听任何可能创建的“a”内存位置,而当以后实际创建“a”位置时,参考系指的是那个地点在javascript';创建阶段';?,javascript,Javascript,我现在正在学习Udemy课程,我刚刚了解了解释器解释JS时发生的创建阶段和执行阶段 我有一个问题,但我将首先向您展示我正在使用的代码: 如果我理解正确,在创建阶段,变量和函数是“设置”的,这意味着它们在内存中被指定了点。变量都被赋予了未定义的占位符值。然后在执行阶段,引擎执行从顶部开始的行。当第一次调用b()时,“a”仍然具有未定义的占位符值,然后将“a”的初始值指定为“peas”,再次调用b(),这次“a”的值为“peas”。 在我看来,这里必须发生两件事中的一件。备选方案1:在创建阶段,所
我在这两种情况下都正确吗?你可以这样想。
您的原始代码:
b();
function b () {
console.log(a);
}
var a = 'peas';
b();
实际上是这样执行的:
var a;
function b () {
console.log(a);
}
b(); // log undefined because a doesn't have a value yet
a = 'peas';
b(); // log peas because a has a value
基本上,所有变量和函数定义都放在封闭范围的顶部。
顺序实际上并不重要,因为函数b
中的代码在实际调用函数之前不会执行
如果我理解正确,在创建阶段,变量和函数是“设置”的,这意味着它们在内存中被指定了点
为此,我不会使用术语set——它通常用于指一个变量被设置(赋值)为一个特定的值。我也不会使用术语“斑点”或“记忆”——我们不需要担心这些内部问题。只需说声明就更清楚了
我也不太喜欢“创造阶段”这个词的使用,它既不标准又令人困惑——到底是什么在创造?我更喜欢“汇编”一词
变量都被赋予了未定义的占位符值
确切地说,我不会说它们“具有未定义的价值”,而是“没有价值”,或“未定义”<代码>未定义不是由尚未指定的变量所持有的值;相反,它是一个状态,当访问该状态时,该状态会导致变量计算为未定义的值
备选方案1:在创建阶段,所有变量都在函数之前设置
是的,尽管再次使用“集合”这个词会让人困惑。比如,“所有变量在函数之前声明”。这是提升的过程
备选方案2:函数和变量按照它们所处的词法顺序设置(在本例中,b是在a之前创建的),当b被创建时,“a”引用以某种方式表示函数正在侦听任何可能创建的“a”内存位置,而当以后实际创建“a”位置时,参考系指的是那个地点
否。该函数不“侦听”任何内容。它只是在你告诉它的时候执行
这重要吗?
不是真的。它属于神秘的范畴。因此,我们用规则堵塞我们的大脑,比如变量以这种方式提升,函数声明以其他方式提升,let
还有其他提升行为。实际上,几乎所有的样式指南都会要求您在函数顶部声明变量,如果您不这样做(或者可以配置为这样做),linter会警告您。这立即消除了所有可变吊装问题
有些人喜欢将内部函数放在函数的底部,这很好,因为如果它是一个函数声明(即function foo(){}
),那么整个过程(包括定义)都会被提升。如果它是一个函数表达式被赋值给一个变量(即var foo=function(){}
),那么它就是一个变量,我们已经决定把它放在函数的顶部——参见上面的段落
一般来说,如果您的程序依赖于提升行为,那么它编写得很糟糕。如果您需要了解提升行为以了解程序的工作方式,那么它的编写就很糟糕
总之,您真正需要学习的只有一条规则:将变量声明(及其初始化)放在函数的顶部。那你就不必担心起重了
(也有一些例外情况,例如在for
语句中声明变量,如for(var i..)
,假设i
不用于循环索引以外的任何内容,这很好。)
出于某种原因,学习JS的人有时似乎会关注这些奇怪的事情——比如“为什么”“==假
或其他什么。我建议你把重点放在如何思考你的问题上,并把它们分解开来,然后编写一个干净的代码,这样你和其他人就可以不用担心这个奥秘而维护它了。我写JS已经很多年了,不记得上次遇到提升相关问题是什么时候了。我不确定实现的细节,但一个好的经验法则是,在var
语句中,变量的声明被提升,但赋值部分没有。所以你的选择2是错误的。关于备选方案1,我认为所有变量和函数都分配了内存
var a;
function b () {
console.log(a);
}
b(); // log undefined because a doesn't have a value yet
a = 'peas';
b(); // log peas because a has a value