JavaScript高级程序设计中的变量和作用域是一个基础而又重要的概念。下面是一个详细的攻略,帮助你深入理解变量和作用域。
变量
声明变量
声明变量是在程序中创建变量的过程。在JavaScript中,可以使用三种关键字来声明变量:
var
let
const
其中,var
是ES5的语法,let
和const
是ES6的语法。使用var
定义的变量的作用域是在函数内,而使用let
和const
定义的变量的作用域是在块级作用域内。
变量提升
变量提升是指在JavaScript中,变量的声明会提前到代码的顶部。这意味着,即使在变量声明之前使用变量,在代码中也不会出错。例如:
console.log(message); // undefined
var message = 'Hello World!';
在上面的代码中,变量message
在被声明之前就被使用了,但是不会报错,因为JavaScript引擎会自动将变量声明提升到代码的顶部,相当于:
var message;
console.log(message); // undefined
message = 'Hello World!';
变量作用域
变量作用域是指变量在程序中可以被访问的范围。在JavaScript中,有两种作用域:
- 全局作用域:任何声明在函数外的变量,包括声明在代码块中的变量,都是全局变量,可以在程序的任何地方访问。
- 函数作用域:任何声明在函数内的变量,只有在函数内部才可以访问。
闭包
闭包是指可以访问另一个函数作用域变量的函数。具体来说,当一个函数返回另一个函数时,返回的函数可以访问其父函数的作用域。示例如下:
function outer() {
var message = 'Hello World!';
function inner() {
console.log(message);
}
return inner;
}
var fn = outer();
fn(); // 'Hello World!'
在上面的代码中,outer
函数返回了inner
函数,inner
函数可以访问outer
函数中声明的变量message
,由于fn
是outer
函数返回的inner
函数的引用,因此fn
可以访问outer
函数的变量。
作用域
函数作用域
在JavaScript中,每个函数都会创建一个新的作用域。在函数作用域内声明的变量只能在该函数内部访问,函数外部无法访问。示例如下:
function foo() {
var message = 'Hello World!';
console.log(message); // 'Hello World!'
}
foo();
console.log(message); // ReferenceError: message is not defined
在上面的代码中,变量message
是在foo
函数内声明的,只能在函数内部使用。在foo
函数外部使用这个变量会导致ReferenceError
错误。
块级作用域
在ES6中引入了let
和const
关键字,可以声明块级作用域的变量。在块级作用域内声明的变量只能在该代码块中使用,如下所示:
if (true) {
let message = 'Hello World!';
console.log(message); // 'Hello World!'
}
console.log(message); // ReferenceError: message is not defined
在上面的代码中,变量message
是在if
代码块中声明的,只能在这个代码块内部使用,在代码块外部使用这个变量会导致ReferenceError
错误。
示例
下面提供两个有关变量的示例:
示例1:变量提升
console.log(message); // undefined
var message = 'Hello World!';
在上面的代码中,虽然message
变量在被使用之前被声明,但是不会报错,因为变量提升将message
变量声明提前到了代码的顶部。输出的结果是undefined
。
示例2:闭包
function counter() {
var count = 0;
return function() {
count++;
console.log(count);
}
}
var fn1 = counter();
fn1(); // 1
fn1(); // 2
var fn2 = counter();
fn2(); // 1
在上面的代码中,counter
函数返回了一个函数,返回的函数可以访问外层函数的局部变量count
。var fn1 = counter()
之后,fn1
就是一个闭包,可以访问counter
函数的作用域,调用fn1
函数两次都会使count
变量自增。var fn2 = counter()
之后,返回的函数也是一个闭包,但是与fn1
的闭包是两个不同的作用域,因此fn2
自己维护了一个count
变量,并且与fn1
的count
变量是不同的。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript高级程序设计之变量与作用域 - Python技术站