原文地址:https://dev.to/bhagatparwinder/scope-in-javascript-3jim
JavaScript 中的作用域规定了一个变量或函数的可用范围。根据变量或函数的声明位置它们或许只能在个别 JavaScript 代码块中可用在其他地方则不行。我们在 JavaScript 中会接触到三种作用域。
当一个变量/方法在 script 或 JS 文件中(不属于任何一个函数)声明 并且可以那个文件或者 HTML 文档中引用到,它就是被声明在了全局作用域。它不属于某个方法或模块。
在浏览器中,有一个全局变量叫 window,你可能会看到开发者经常把 window.setInterval 和 setInterval 交换使用而没有带来后果或副作用,那是因为 setInterval 在全局作用域中。浏览器在 window 对象上还提供了许多其他的全局方法。
声明变量的方法有三种:const 、let、var,它们都可以声明全局变量,但只有 var 声明变量挂在到了 window 上。
当在一个函数中声明一个变量时,它只能在函数中使用外面无法使用。因为它的作用域只归属于函数。
const first = "Parwinder"
function sayLastName() {
const last = "Bhagat";
}
console.log(first); // Parwinder
console.log(last); // Reference Error: last is not defined
正如你所见,last 在函数外面是无法使用的,在 sayLastName 中是可以使用的。
const first = "Parwinder"
function sayLastName() {
const last = "Bhagat";
console.log(last); // Bhagat
}
sayLastName(); // Remember, I have to call a function to execute the code block in it.
console.log(first); // Parwinder
我们可以读取全局变量并在任何地方使用,同样使用上面的例子:
const first = "Parwinder"
function sayLastName() {
console.log(first); // Parwinder
const last = "Bhagat";
console.log(last); // Bhagat
}
sayLastName();
console.log(first); // Parwinder
即使我不能在函数外中获取 last ,但依旧可以在函数中获取全局变量 first 。这是因为在 JavaScript 中当解释器读取一个变量时,首先在当前作用域中查找,若没有则会向上层作用域查找。在这个例子中,当我们在 sayLastName 中打印 first 时,JS 引擎首先会在函数作用域中查找,之后在全局作用域中查找。若任何作用域中都没有找到,则会报一个引用的错误。
块级作用域是被定义在一对大括号中的。根据定义函数是一个快,但函数中还有更小的快。函数中的 for loop 或 if 语句都有它们自己的块级作用域。块级作用域帮助我们在代码中组织了很小的作用域。
创建块级作用域方法是使用 const 或 let 在大括号中声明变量。
function amICool(name) {
let attribute;
if (name === "Parwinder") {
attribute = "cool"
}
return attribute;
}
console.log(amICool("Parwinder")); // cool
console.log(amICool("Bhagat")); // undefined because the name was not "Parwinder"
上面的例子是为 attribute 创建了函数作用域,我们可以把它缩小些:
function amICool(name) {
if (name === "Parwinder") {
let attribute = "cool"
}
return attribute; // Reference error: attribute is not defined
}
console.log(amICool("Parwinder")); // Reference error: attribute is not defined
console.log(amICool("Bhagat")); // This will not run as we ran into an error with the first execution of the function
发生了什么?let 使 attribute 变量属于块级作用域,此时它被限制在 if 语句中。当我们尝试在 if 语句外返回它时,attribute 是找不到的。
一个经验:首先使用 const 来声明变量,若变量的值会变动,则使用 let 次之,var 是最后的选择。
等等,这是什么?不是说只有三种作用域吗?词法作用域是 JavaScript 中使用的作用域模型。变量或函数的作用域是它们被定义时所在的作用域。
const myName = "Parwinder";
function sayMyName() {
console.log(myName);
}
function sayMyNameAgain() {
const myName = "Bhagat";
sayMyName();
}
sayMyNameAgain();
输出 Parwinder ,为什么:
因为 sayMyName 是在声明它的作用域下执行的。