JavaScript作用域
- JavaScript中有全局作用域和局部作用域
- 相同作用域内不能有同名的变量和函数
- 不同作用域内可以有同名的变量和函数
- 在js中如果不同的作用域中出现了相同名称的变量, 那么访问时采用
就近原则
作用域链
- 默认情况下全局作用域, 我们称之为
0级作用域
- 只要定义一个函数就会再
开启一个作用域
- 如果该函数是在全局作用域中定义的, 那么我们称之为
1级作用域
- 如果该函数是在其他函数中定义的, 那么所在函数
+1级作用域
- 作用域链的作用:
在使用变量或者函数的时候, 会在当前作用域链中查找, 如果找不到, 就会去上一级的作用域链中查找
注意点:
在JavaScript中, 函数是可以嵌套定义的
//num属于0级作用域
var num = 123;
// test函数也属于0级作用域
function test() {
// test的{}中是新开启的一个作用域
// test的{}中定义的变量和函数都属于1级作用域
// value属于1级作用域
var value = 666; // 1级作用域
// demo函数也属于级作用域
function demo() {
// demo的{}中是新开启的一个作用域
// demo的{}中定义的变量和函数都属于2级作用域
// temp属于2级作用域
var temp = 678;
console.log(temp);
}
}
注意点:
1.默认情况下在一对script标签或者在一个单独的JS文件中定义的变量都是全局变量
- 默认情况下在函数中定义的变量都是局部变量
- 但是如果在函数中定义变量时, 没有书写var关键字, 那么这个局部变量就会变为全局变量
- 虽然这样可以将一个局部变量变为全局变量, 但是在企业开发中千万不要这样写
function test() {
//在企业开发中不要这样写
num = 10;
console.log(num);
}
test();
console.log(num);
预解析
- 什么是预解析
- 我们都知道js是解释性的语言, 也就是不需要编译, 边执行边解析
- 浏览器的JS解析引擎在执行JS代码之前会做一件事情, 就是预解析
- 将变量和函数的声明提升到当前作用域的最前面, 这个我们就称之为
预解析
/*
预解析之后的代码
JS解析引擎执行的是如下代码, 而不是我们编写的代码
// 1.将变量的声明放到当前作用域的最前面
var num;
// 2.将其它的代码按照编写的顺序依次放到后面
console.log(num);
num = 123;
*/
console.log(num);
var num = 666;
/*
1.将函数的声明放到当前作用域的最前面
function test() {
console.log("test");
}
// 2.将其它的代码按照编写的顺序依次放到后面
test();
alert(test);
*/
demo();
function demo() {
console.log("打印");
}
注意点:
在企业开发中变量的名称千万不要和函数的名称一样, 否则会出现混乱问题
规则:
如果在同名的变量和函数声明之前访问这个名称, 拿到的是函数
如果在同名的变量和函数声明之后访问这个名称, 拿到的是变量
//打印的是num函数
//console.log(num);
function num() {
console.log("我是函数");
}
var num = 666;
//打印的是数值666
console.log(num);
两种定义函数方式预解析区别
- 通过
函数声明的方式
定义函数,在预解析的时候会
把函数声明提升到最前面 - 通过
变量定义的函数
,在预解析的时候不会
把函数声明提升到最前面
test();
// fn(); //会报错
function test() {
console.log("打印点东西");
}
// 通过变量来定义
// 通过函数表达式的方式定义
var fn = function () {
console.log("继续打印点东西");
}
注意点
在高级别的浏览器中, 预解析不会提升{}中的函数
但是在低级别的浏览器中, 预解析会提升{}中的函数
if(true){
// 前面我们说过默认都是0级作用域, 也就是全局作用域
// 只有定义了函数才会开启一个新的作用域
// 所以test函数虽然定义在了if的{}中, 但是并没有定义在其它函数中
// 所以test函数还是属于0级作用域, 所以还是一个全局函数
function test() {
console.log("test1");
}
}else{
function test() {
console.log("test2222222");
}
}
test();
// 在低级别IE浏览器中的问题
// 高级版本的浏览器不会提升{}中的函数
function test() {
console.log("test1");
}
function test() {
console.log("test2222222");
}
if(true){
}else{
}
test();
网友评论