作用域
- JavaScript中也有作用域的概念
- 相同作用域内不能有同名的变量和函数, 不同作用域内可以有同名的变量和函数
- 如果不同的作用域中出现了相同名称的变量, 那么访问时采用就近原则
var num = 123;
function say() {
var num = 666;
console.log(num); //666
}
say();
作用域链
- 默认情况下全局作用域,我们称之为0级作用域
定义一个函数就会再开启一个作用域,如果该函数是在全局作用域中定义的, 那么我们称之为1级作用域.如果该函数是在其他函数中定义的,那么所在函数+1级作用域
- 作用域链的作用
在使用变量或者函数的时候,会在当前作用域链中查找, 如果找不到, 就会去上一级的作用域链中查找
- 在JS中,函数可以嵌套定义
var num = 666;
function say() {
var num = 123;
var test = function () {
var num = 777;
console.log(num); //777
};
console.log(num); //666
test();
}
console.log(num); //123
say();
全局变量
- 默认情况下在函数中定义的变量都是局部变量
- 在函数中定义变量时,没有书写var关键字,那么这个局部变量就会变为全局变量(==企业开发中不能写==)
function say() {
num = 666;
console.log(num);
}
say(); //666
console.log(num); //666
预解析
- js是解释性的语言,不需要编译, 边执行边解析
- 预解析在JS代码执行前
- (预解析)将变量和函数的声明提升到当前作用域的最前面
console.log(num);//undefined
var num = 123;
//1.var num;
//2.console.log(num);
//3.num = 123;
say();//hello
function say() {
console.log("hello");
}
//1. function say() {console.log("hello");}
//2. say();
- 预解析练习1:
var num = 123;
fun();
function fun() {
console.log(num);//undefined
var num = 666;
}
- 预解析练习2
var a = 666;
test();
function test() {
var b = 777;
console.log(a); //undefined
console.log(b); //777
var a = 888;
}
- 预解析练习3
变量和函数同名时,函数的优先级最高
console.log(num);//ƒ num() {console.log("hello world");}
function num() {
console.log("hello world");
}
var num = 666;
console.log(num); //666
- 企业开发中:变量名与函数名不能一样,否则会出现混乱问题
- 规则:
如果在同名的变量和函数声明之前访问这个名称, 拿到的是函数
如果在同名的变量和函数声明之后访问这个名称, 拿到的是变量
// var num = 123;
// function num() {
// console.log("hello");
// }
// console.log(num); //123
console.log(num);//ƒ num() {console.log("hello");}
var num = 123;
function num() {
console.log("hello");
}
不同方式定义函数的区别
- 在高级别的浏览器中,预解析不会提升{}中的函数
- 在低级别的浏览器中,预解析会提升{}中的函数
if (true){
function test() {
alert("hello");
}
}else {
var test = function () {
alert("world");
}
}
test();
//前面我们说过默认都是0级作用域, 也就是全局作用域
//只有定义了函数才会开启一个新的作用域
//所以test函数虽然定义在了if的{}中, 但是并没有定义在其它函数中
//所以test函数还是属于0级作用域, 所以还是一个全局函数
网友评论