作用域
概念
作用域就是变量的可用范围(scope)
为什么要有作用域
目的是防止不同范围的变量之间互相干扰
有几种作用域
- 全局作用域
- 概念:
不属于任何函数的外部范围称为全局作用域;保存在全局作用域的变量称为全局变量 - 优点: 可反复使用
- 缺点:全局污染
- 概念:
- 函数作用域
一个函数内的范围称为函数作用域; 保存在函数作用域内的变量称为局部变量;- 优点: 不会被污染
- 缺点: 无法反复使用
特例:形参变量也是函数内的局部变量; fucntion f(y){ // y 为局部变量} 举例:
var x = 1; // 全局作用域
function f(){
var y = 2; // 局部作用域
}
强调: 只有函数的{},才能形成作用域;
- 不是所有{}都能形成作用域。
- 也不是所有{}内的数据都能是局部变量
- 举例:
- 对象的{},就不是作用域!
- 对象中的属性,也不是局部变量;
var lilei={
sname: “Li Lei”,
intr:function(){
console.log(“我是${this.sname}”) // 为什么这里必须加this?
// 因为:都是因为对象的{}不是作用域,对象中的属性不是局部变量。
}
}
强调: JS中没有块级作用域
- 除
函数{}之外的其余{},都不是作用域。 - 都
拦不住内部的变量超出{}的范围影响外部程序 - 举例:
console.log(a); //不报错, undefined
if(false){ //不是作用域,拦不住变量被声明提前
var a=10;
}
console.log(a); // 10
作用域链
概念:
一个函数可用的所有作用域串联起来,就行成了当前函数的作用域链。
解析:其实每个函数在定义时,就已经规划好了自己专属的一个查找变量 的路线图,称为作用域链。
如下图:看看什么是作用域链;
特殊: 给从未声明过的变量赋值
总结:
Js中只有
两种局部变量:①:函数内var出来的 ②:函数的形参变量;
看不见var,形参里也没有就不是局部变量。
举例三道题用来理解,局部变量、全局变量以及作用域链
题一:
var a = 10 、、 全局变量
function fun(){
var a= 100; // 局部变量
a++
console.log(a) // 101
}
fun();
console.log(a) // 10
题二:
var a = 10 // 全局变量
function fun(){
a= 100; // 给全局变量赋值
a++
console.log(a) // 101
}
fun();
console.log(a) // 101
题三:
var a = 10 // 全局变量
function fun(a){
a++; // 传入的a为局部变量,给a做运算
console.log(a) // 11
}
fun(a);
console.log(a) // 10
作用域的本质:作用域和作用域链都是对象结构
总结:
全局作用域其实是window对象;所有全局变量和全局函数都是window对象的成员
补充:函数作用域 -- 又叫:活动的对象(ActivedObject) --简称, AO。
概念:其实是js引擎在调用函数时才临时创建的一个作用域对象。其中保存函数的局部变量。而函数调用完,函数作用域对象就释放了。
直观对比:
函数作用域创建:
函数作用域销毁:函数执行完之后,立即销毁,所以局部变量不可重用;