让我们来看看新的Var



当我们学习一种编程语言时,会出现几个基本概念,例如声明变量,它们是如此简单,以至于我们可以在不了解其功能的情况下开始使用它们。

我知道您的想法:“您为什么要浪费时间写信给我们?”

因为我认为值得花几分钟来更好地理解这些元素,它们的含义是什么以及我们应该如何使用它们。 这将帮助您避免一些常见的错误并更好地编写代码。

在本文中,我们将重点介绍如何在JavaScript中存储数据。

Var


“曾经在遥远的银河系中……”在JavaScript中定义变量的唯一选择是使用var关键字,这足以操纵代码中的数据。 但是随着ES6标准的引入,旧JS的一些奇特之处和弱点变得非常明显:

  1. 作用域:var关键字仅允许您在全局和局部作用域(或函数作用域)中定义变量。 无论您有多少嵌套的代码块,都只有这两种可能性。
  2. 常量:如果要定义在代码执行期间不会更改的内容,则只能依靠开发人员的常识。 我们可以使用一些有用的约定来阐明含义(例如,大写字母),但是并不能保证含义不会改变。
  3. 覆盖变量:可以重复声明同一变量多次(在同一范围内),如果要保持变量唯一,这会有些混乱。

定义


在开始介绍技术知识之前,让我们介绍一些常规定义:

变量是存储可重用数据的“容器”(非常琐碎)。

标识符是变量名(也很简单)。

是由一对大括号( ccskrf )分隔的一段代码,例如:if,for,function和。 等

范围 ,确定代码中变量的可见性。 如果您有任何疑问,请问自己:“代码中我的变量在哪里可见?”
注意 请不要将范围执行上下文混淆, 执行上下文是不同的。

**上下文(或执行上下文)**是执行JavaScript代码的环境。 为简单起见,我们可以说上下文是代码所属的对象, 是引用它的关键字。 因此,问问自己:“这是指什么对象?”

现在,假设我们的开发人员对《星球大战》非常热衷(这很好),但是尽管已经存在了一段时间,但对诸如ES6之类的新标准却很怀疑(这很不好)。 因此,他更喜欢以旧的ES5风格编写代码,看起来像这样:

console.log("I am a %s", jedi); var jedi = "Ani"; //   jedi    // =>  undefined function useTheForce(comeToTheDarkSide) { var jedi = "Obi-Wan Kenobi"; var jedi = "Anakin Skywalker"; if (comeToTheDarkSide) { var jedi = "Darth Vader"; console.log("I am %s", jedi); // => I am Darth Vader } console.log("I am %s", jedi); //  Darth Vader } useTheForce(true); console.log("I am %s", jedi); // => Ani 

如您所见,有三个代码块(包括全局代码),但是只有两个作用域。 这是因为if括号中的代码未创建作用域。 控制台将两次发布“ I am Darth Vader”,然后在全球发布“ I am Ani”。

还要注意,同一变量在函数内部连续声明两次,然后在if语句中再次声明。 这意味着我们在相同的作用域中有三次相同的变量声明,这将引发异常。

最后但并非最不重要的一点是,第一个日志的输出是:在定义变量之前,我们先打印变量的值。 这对于var是完全合法的,称为“吊装”。

“爬升”假定已声明的变量和函数实际上已移动到代码的开头。 从技术上讲,有一些变量和函数的声明在编译阶段存储在内存中,但仍保留在代码中的确切位置。 提升的根本重要性在于,它允许您在代码中声明函数之前使用它们。

你可以在这里阅读。

在我们的示例中,变量“ jedi”的声明被放置在内存中并初始化为默认值(未定义)。


目前,我们的开发人员知道ES6还不错,因此他决定给一个机会:

 console.log("I am a %s", jedi); let jedi = "Ani"; //   jedi    // => Uncaught ReferenceError:     "jedi"   function useTheForce(comeToTheDarkSide) { let jedi = "Obi-Wan Kenobi"; let jedi = "Anakin Skywalker"; // => Uncaught SyntaxError:  ''   if (comeToTheDarkSide) { var jedi = "Darth Vader"; console.log("I am %s", jedi); // =>  Darth Vader } console.log("I am %s", jedi); //  Anakim Skywalker } useTheForce(true); console.log("I am %s", jedi); // =>  Ani 

但是他很快意识到,他不能仅仅将var关键字更改为let,为此,您需要进行一些更正:

上升的工作方式不同:将变量置于称为临时死区* *的状态,并且直到对定义求值后才对其进行初始化。 在我们的示例中,它引发错误:引用错误。

禁止重新分配 ,作用域中变量的定义必须唯一。 尝试获取错误时:SyntaxError。

if语句是有效的块范围,因此其中的jedi声明是唯一的。

现在的代码应该是这样的:

 let jedi = "Ani"; console.log("I am a %s", jedi); // print jedi variable before defining it // =>  Ani (  ) : 0 function useTheForce(comeToTheDarkSide) { let jedi = "Obi-Wan Kenobi"; let jedi = "Anakin Skywalker"; if (comeToTheDarkSide) { var jedi = "Darth Vader"; console.log("I am %s", jedi); // =>  Darth Vader } console.log("I am %s", jedi); //  Anakim Skywalker } useTheForce(true); console.log("I am %s", jedi); 

康斯特


既然您已经了解了let的全部知识,那么很容易向您介绍const 。 本质上,我们可以说const与let类似,但是您不能重新分配另一个值。 您还需要知道仅在const声明期间才允许分配。

 function useTheForce(comeToTheDarkSide) { const jedi = "Yoda"; if (true) { jedi = "Darth Yoda"; console.log("I am %s", jedi); // => TypeError: Assignement to constant variable. } } useTheForce(true); 

假设在我们的示例中,“ jedi”是一个值为“ Yoda”的常量,如果我们尝试在if语句中更改该值,则会给我们带来TypeError错误,这是可以理解的,因为Yoda永远不会加入阴暗面。

结论


当无法用语言用语言表达概念时,会引入一个新概念来填补空白。 这对于英语( 链接 ),意大利语,世界语,ewokese(我想)等是正确的。对于诸如JavaScript之类的编程语言而言,这更为正确。

现在您知道您可以:

  • 在块范围内声明变量并仅在评估块时为其分配内存
  • 使变量声明在范围内唯一,避免开发人员错误地覆盖代码另一部分中使用的变量(具有不同的值)
  • 我们可以确保const中存储的变量不会随时更改。

我的最后一个提示是使用const作为默认选择。 当您需要重新分配变量时,请使用** let **(如循环所示)。 并在以下情况下使用var ...不,您实际上不再需要var

谢谢您的关注。

快速Javascript问题

我在TwitterVK上

Source: https://habr.com/ru/post/zh-CN466559/


All Articles