您是否曾经觉得自己的JavaScript代码在做奇怪的事情,或者您不明白为什么有不确定的变量?您确保初始化并为此变量分配一个值?
好吧,实际上没有什么奇怪的,我们只是忘记或不知道我将在下面显示的一些基本和简单的原则,以免您再次忘记它们。
范围,提升和时间死区,这就是这篇文章的内容
范围
什么是?
范围确定代码每个部分中变量的可访问性。
在JavaScript中,我们有不同类型的范围:
全局范围
当变量在函数或块之外声明时,一个变量在全局范围中。我们将能够从代码的任何部分(无论是在函数内部还是外部)访问这些类型的变量。
var name = "Leonardo";
// The code written in this part will be able to access name.
function myFunction() {
// The code written in this part will also be able to
access name.
}
本地范围
我们在函数中定义的变量是局部变量,也就是说,它们在局部范围中找到。这意味着这些类型的变量只能在我们声明它们声明的函数中生存,如果我们尝试在其外部访问它们,这些变量将无法定义。
// The code written in this part will NOT be able to access the variable name.
function myFunction() {
var name = "Leonardo";
// The code written here can access to the variable.
}
块范围
与本地范围不同,此范围仅限于定义变量的代码块。由于ecmascript 6,我们拥有允许我们具有块范围的LET和CONST关键字,这意味着变量仅在相应的代码块中生存。
if (true) {
// this if block does not create a scope
// variable name is global because of the use of the 'var' keyword
var name = 'Leonardo';
// country is in the local scope because of the use of the 'let' keyword
let country = 'Mexico';
// language is also a local scope because of the use of the 'const' keyword
const language = 'Javascript';
}
console.log(name); // prints 'Leonardo'
console.log(country); // Uncaught ReferenceError: country is not defined
console. log(language); // Uncaught ReferenceError: language is not defined
词汇范围
词汇范围意味着在嵌套的函数组中,内部函数可以访问其父范围的变量和其他资源。这意味着儿童功能与父母的执行环境联系在一起。
function myFunction() {
var name = 'Leonardo';
// we can't access language from here
function parent() {
// name is accessible from here.
// language is not accessible.
function child() {
// We can also access name from here.
var language = 'Javascript';
}
}
}
提升
什么是?
概念上,例如,对提升的严格定义表明,变量和函数声明物理上移至代码的开始,但实际上并非如此。
发生的事情是,在编译阶段将变量和函数的声明分配在内存中,但它们仍然是您在代码中写下的。
用功能提升的示例
hello("Leo");
function hello(name) {
console.log("Hello " + name);
}
/*
Printed Result "Hello Leo"
*/
提升的JavaScript中的优点之一是,它允许您在代码中声明函数之前使用函数。
您可以看到,即使我们首先在代码中调用该函数,在编写之前,代码仍然有效。
时间死区
什么是?
时间死区(TDZ)是一个块的区域,该区域无法访问变量,直到计算机用值完全初始初始初始初始初始初始化。
假设您尝试在变量完整初始化之前访问。在这种情况下,JavaScript将抛出一个ReferenceError
。
所以,为了防止JavaScript丢弃这样的错误,您必须记住从时间死区外访问变量。
但是TDZ(时间死区)到底在哪里开始和结束?
// TDZ start here
console.log(name); // returns ReferenceError because name TDZ are present
let name = "Leonardo" // TDZ ends
// TDZ not exist here
这是您可以在完整初始化后成功访问name
的方法:
let name = "Leonardo"; // name TDZ ends here
console.log(name); // returns "Leonardo" because name TDZ does not exist here
让变量的所有时间死区原理也适用于const。但是,var的工作方式不同。
var的时间死区之间的主要区别,让和const variable是当它们的tdz结束时。
// name TDZ starts and ends here
console.log(name); // returns undefined because name TDZ does not exist here
var name = "Leonardo"; // name TDZ does not exist here
console.log(name); // returns "Leonardo" because name TDZ does not exist here
console.log语句成功返回了一个值(未定义),因为JavaScript自动将未定义分配给吊装var变量。
换句话说,当JavaScript提升量变量时,它会自动用不确定的值初始化该变量。
相比之下,JavaScript不会在吊起变量时初始化具有任何值的LET(或CONST)变量。相反,该变量保持死亡和无法访问。
因此,当JavaScript用声明期间指定的值完全初始初始初始初始初始初始初始初始初始初始初始化了
时,LET(或CONST)变量的TDZ结束。然而,var变量的升起后立即结束,而不是在变量在声明过程中指定的值完全初始化时。
结论
这些是我们许多人没有意识到的基本概念,因为我们开始编程而不了解语言的工作原理,而是直接抛出代码,但是知道语言是如何工作的,并且知道这些基本概念会使我们变得更好开发人员生成最佳解决方案。