Scope(作用域)
当前的执行上下文。 值 和表达式在其中 “可见” 或可被访问到的上下文。如果一个 变量 或者其他表达式不 “在当前的作用域中”,那么它就是不可用的。
作用域也可以根据代码层次分层,以便子作用域可以访问父作用域,通常是指沿着链式的作用域链查找,而不能从父作用域引用子作用域中的变量和引用。
Block (块作用域)
在 JavaScript中, 函数块 是指被大括号 (“{}”) 包裹住的相关联的 statements 的集合。
例如,你可以在 if (condition)后声明一段函数块形式的代码,表明当条件判断为真时,解释程序应该运行上述函数块里的代码,或者当条件判断为假时跳过执行上述函数块里的代码。
var
- 在函数作用域或全局作用域中通过关键字 var 声明的变量,无论在哪里声明,都会 被当成在当前作用域顶部声明的变量 ,这就是JavaScript的 变量提升 机制。
- 用var声明的变量可以重复声明。例如var a = function(){}后接var a = 1,a值会变成1。
变量提升 :函数声明及var声明的变量会得到提升。但是函数声明会先于var声明的变量被提升。即便function写在后面。
// 块(作用域)中
{
var a = 1;
}
console.log(a); // 1
// 函数内部
function showValue(flag){
if(flag){
var b = 1;
}else{
console.log(b);
}
}
showValue(true); // b 值为 1
showValue(false); // b 值为 undefined
// 在循环中
for(var c = 0; c < 10 ; c++){
}
console.log(c); // 10
let
- 为了更好的体现作用域的概念,减少因为变量提升带来的赋值影响,ES6开始引入 let 声明变量,用法与 var 相同,let的作用限制在当前代码块中。
- 用let声明的内容在 同作用域 不可重复声明,例如let a = function(){}后接let a = 1,会报错:
Uncaught SyntaxError: Identifier 'a' has already been declared
。
// 块(作用域)中
{
let a = 1;
}
console.log(a); // Uncaught ReferenceError: a is not defined
// 函数内部
function showValue(flag){
if(flag){
let b = 1;
}else{
console.log(b);
}
}
showValue(true); // b 值为 1
showValue(false); // Uncaught ReferenceError: b is not defined
// 在循环中
for(let c = 0; c < 10 ; c++){
}
console.log(c); // Uncaught ReferenceError: c is not defined
// 不同作用域可以重复声明
let d = 2
{
let d = 1;
console.log('In:'+ d); // In:1
}
console.log('Out:'+ d); // Out:2
const
- ES6引入 const 关键字声明常量,且必须在声明时初始化(赋值)。
- 用const声明的内容在 同作用域 不可重复声明,例如const a = function(){}后接const a = 1,会报错:
Uncaught SyntaxError: Identifier 'a' has already been declared
。 - 用const声明的内容:
基本类型无法修改,
引用类型本身绑定也无法修改,但是对象的属性和值是可以改变的。
// 块(作用域)中
{
const a = 1;
}
console.log(a); // Uncaught ReferenceError: a is not defined
// 函数内部
function showValue(flag){
if(flag){
const b = 1;
}else{
console.log(b);
}
}
showValue(true); // b 值为 1
showValue(false); // Uncaught ReferenceError: b is not defined
// 不同作用域可以重复声明
const c = 2
{
const c = 1;
console.log('In:'+ c); // In:1
}
console.log('Out:'+ c); // Out:2
// 基本类型
const d = 1;
const d = 2; // Uncaught TypeError: Assignment to constant variable.
// 引用类型
const e = {
index: 1
};
//增
e.numOrString = 'name';
e.toDelete = 'delete';
console.log(e); // {index: 1, numOrString: "name", toDelete: "delete"}
//删
delete e.toDelete;
console.log(e); // {index: 1, numOrString: "name"}
//改
e.numOrString = 1;
console.log(e); // {index: 1, numOrString: 1}