JavaScript基础笔记
1 作用域
1.1 作用域概述
变量起作用(可被访问)的范围。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了变量名冲突。
JavaScript(es6前)中的作用域有两种:
- 全局作用域
- 局部作用域(函数作用域)
1.2 全局作用域
作用于所有代码执行的环境
- (整个 script 标签内部)或者一个独立的 js 文件。
1.3 局部作用域
作用于函数内的代码环境,就是局部作用域。
- 表示
函数
内部环境,所以也称为函数作用域。
1.4 ES5没有块级作用域
- 块作用域由 { } 包括。
块级作用域和局部(函数)作用域是不同概念,每个花括号内部就是一个块级作用域,常见有流程语句、函数体
-
在其他编程语言中(如 java、c#等),在 if 语句、循环语句中创建的变量,仅仅只能在本 if 语句、本循环语句中使用,如下面的Java代码:
java有块级作用域:
if (true) { int num = 123; system.out.print(num); // 123 } system.out.print(num); // 报错,提示num未被定义
-
关键字var声明的变量没有块级作用域概念
- 即
var声明的变量只区分函数体和函数外环境
- 函数体:每个function所属的{}区域内
- 外部环境:函数除外的代码,包括变量声明、函数调用、条件语句(即包括条件语句{}内的代码)等
// num是全局变量 if(true){ var num = 123; console.log(num); //123 } console.log(num); //可访问if语句块的变量,输出123 // 以下代码外循环只循环了一次,内循环循环五次 // 因为内循环的i和外循环的i是同一个变量(全局变量) for (var i = 0; i < 5; i++) { for (var i = 0; i < 5; i++) { //内循环第一次循环就把外循环的i值从0赋到了5 console.log('内' + i); } // 下面的输出只执行了一次, console.log('外' + i); }
在ES6之前,声明变量的关键字只有var
- 即
2 变量与作用域
在JavaScript中,根据作用域的不同,变量可以分为两种:
- 全局变量
- 局部变量
2.1 全局变量
在全局作用域下声明的变量叫做全局变量(在函数外部定义的变量)。
- 全局变量在代码的任何位置都可访问
-
在全局作用域下 var 声明的变量,是全局变量
-
不声明,直接赋值的变量,即使在函数内出现,也是全局变量(避免使用)
function fn() { var a = 1; b = 2; } fn(); console.log(b);// 输出2 console.log(a);// 报错,a 未被定义
- 注意:需要调用一下fn(),不然 b=2; 这句代码不会被执行,b变量也不会被申请
-
2.2 局部变量
在局部作用域下声明的变量叫做局部变量(在函数内部定义的变量)
- 局部变量只能在该函数内部使用
- 在函数内部 var 声明的变量是局部变量
- 函数的形参实际上就是局部变量
2.3 全局变量和局部变量的区别
-
全局变量:任意地方可访问
- js执行就会被初始化;只有在浏览器关闭时才会被销毁,比较占内存
-
局部变量:只在函数内部使用
- 当其所在的代码块被执行时,才会被初始化;当函数代码块运行结束后,就会被销毁,更节省内存空间
函数体内不声明直接赋值的变量,在函数结束后不会随函数一起销毁,而成为全局变量
3 作用域链
根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链
- 即作用域内可能嵌套作用域,当存在多级作用域嵌套时,变量的访问机制是:先从自己的作用域查找,再
逐级往上查找
,找到了就停止,不再往上找。
函数内定义的函数可访问外部函数的变量
function f1() {
var num = 123;
function f2() {
console.log( num );
}
f2();
}
var num = 456;
f1();// 输出 123
作用域链:采取就近原则,离自身作用域最近的变量会覆盖其它同名变量
var a = 1;
function fn1() {
var a = 2;
var b = '22';
fn2();
function fn2() {
var a = 3;
fn3();
function fn3() {
var a = 4;
console.log(a); //a的值 4
console.log(b); //b的值 22
}
}
}
fn1();