什么是作用域
Javascript中的作用域说的是变量的可访问性和可见性。也就是说整个程序中哪些部分可以访问这个变量,或者说这个变量都在哪些地方可见。
作用域的类型
- 全局作用域
- 函数作用域
- 块级作用域
1.全局作用域
任何不在函数中或是大括号中声明的变量,都是在全局作用域下,全局作用域下声明的变量可以在程序的任意位置访问。例如:
// 全局变量 var greeting = 'Hello World!'; function greet() { console.log(greeting); } // 打印 'Hello World!' greet();
2.函数作用域
函数作用域也叫局部作用域,如果一个变量是在函数内部声明的它就在一个函数作用域下面。这些变量只能在函数内部访问,不能在函数以外去访问。例如:
function greet() { var greeting = 'Hello World!'; console.log(greeting); } // 打印 'Hello World!' greet(); // 报错: Uncaught ReferenceError: greeting is not defined console.log(greeting);
3.块级作用域
ES6引入了let
和const
关键字,和var
关键字不同,在大括号中使用let
和const
声明的变量存在于块级作用域中。在大括号之外不能访问这些变量。看例子:
{ // 块级作用域中的变量 let greeting = 'Hello World!'; var lang = 'English'; console.log(greeting); // Prints 'Hello World!' } // 变量 'English' console.log(lang); // 报错:Uncaught ReferenceError: greeting is not defined console.log(greeting);
注意:上面代码中可以看出,在大括号内使用var
声明的变量lang是可以在大括号之外访问的。使用var
声明的变量不存在块级作用域中。
作用域链
当在Javascript中使用一个变量的时候,首先Javascript引擎会尝试在当前作用域下去寻找该变量,如果没找到,再到它的上层作用域寻找,以此类推直到找到该变量或是已经到了全局作用域。
如果在全局作用域里仍然找不到该变量,它就会在全局范围内隐式声明该变量(非严格模式下)或是直接报错。
let foo = 'foo'; function bar() { let baz = 'baz'; // 打印 'baz' console.log(baz); // 打印 'foo' console.log(foo); number = 42; console.log(number); // 打印 42 } bar();
什么是词法环境?
所谓词法环境就是一种标识符—变量映射的结构(这里的标识符指的是变量/函数的名字,变量是对实际对象[包含函数和数组类型的对象]或基础数据类型的引用)。
简单地说,词法环境是Javascript引擎用来存储变量和对象引用的地方。
注意:不要混淆了词法环境和词法作用域,词法作用域是在代码编译阶段确定的作用域(译者注:一个抽象的概念),而词法环境是Javascript引擎用来存储变量和对象引用的地方(译者注:一个具象的概念)。
js引擎如何进行变量查找呢?
let greeting = 'Hello'; function greet() { let name = 'Peter'; console.log(`${greeting} ${name}`); // Hello Peter } greet(); { let greeting = 'Hello World!' console.log(greeting); // Hello World! }
上述代码加载后,首先会创建一个全局此法环境,其中包含在全局范围内声明的变量和函数。
注意:
①只有let
和const
声明变量才会创建一个新的词法环境存储,使用var
声明的变量会被存储在当前块(大括号)所在的词法环境中(全局词法环境或是函数词法环境中)。
②当一个变量被使用时,Javascript引擎会首先在当前的词法环境中进行寻找,如果找不到就找上层词法环境中寻找,直到找到为止。
标签:console,变量,作用域,JavaScript,greeting,词法,理解,log From: https://www.cnblogs.com/alwaysrun/p/17177992.html