js中作用域和作用域链scope&scopes

227 阅读3分钟

什么是作用域

作用域是在运行时代码中的某些特定部分中变量,函数和对象的可访问性。换句话说,作用域决定了代码区块中变量和其他资源的可见性。

  • 浅显理解:作用域就是变量的可用范围
  • 为什么要用有作用域:目的是防止的变量之间互相干扰。
  • js中包括2级作用域:

image.png

  • 全局作用域:不属于任何函数的外部范围称为全局作用域。保存在全局作用的变量称为全局变量。
  • 全局变量优点:可以反复使用
  • 全局变量缺点:全局污染--开发时禁止去使用
  • 函数作用域:

image.png

  • 特列:形参变量也时函数内的局部变量

image.png

  • 局部变量的特点
  • 优点:不会被污染
  • 缺点:无法反复使用

强调:只有函数的{},才能形成作用域

  • 不是所有{}都能形成作用域。
  • 也不是所有{}内的数据都是局部变量
  • 比如:
    • 对象的{},就不是作用域
    • 对象中的属性,也不是局部变量

强调:js中没有块级作用域

  • 除函数{}之外的其余{},都不是作用域。
  • 都拦不住内部的变量超出{}的范围影响外部程序 比如:
console.log(a);//不报错,undefined
if(false){不是作用域,拦不住变量被声明提前
    var a=10;
}
console.log(a);//不报错,undefined

作用域链

  • 因为,js规定,一个函数,既能用自己作用域的变量,又能用外层作用域的变量。
  • 所以,需要一个 路线图 告诉每个函数,自己都可以去哪里找到想用的变量。
  • 就像生活中我们规划旅游景点的游览路线一样
  • 其实每个函数在定义时,就已经规划好了自己专属的一个查找变量的路线图,称为作用域链
  • 函数g就为自己规划好了一个由内向往的查找路线

image.png

  • 当执行到某条语句时,js引擎会自动延函数的作用域连查找要用的变量,查找路径时这样的:

image.png

特殊:给从未声明过的变量赋值

  • 如果程序给i赋值,不会报错,从未声明会自动在全局创建变量i

image.png

  • 总结:js中只有两种局部变量:
    • 1.函数内var出来的
    • 2.函数的形参变量
    • 看不见var,形参也没有就不是局部变量

函数作用域和作用域链都是对象结构

耳听为虚,眼见卫实

  • 第一步:新建名为test.html的网页,编写一下程序:

image.png

  • 第二步:用浏览器运行,并按f12打开控制台,点击sources image.png
  • 第三步:然后,点击js程序每一行左侧的行号,添加断点,然后刷新页面

image.png

image.png 总结:全局作用域 其实是一个名为window对象所有全局变量和全局函数都是window对象的成员。

  • 第四步:展开fun函数,看scopes作用域链部分,你有发现什么?

image.png

  • 第五步:点2下左上角蓝色向右三角,让程序运行到fun函数内第一条语句位置,此时就是引擎已经开始条用fun函数

image.png

  • 第六步:连续点击左上角蓝色向右箭头,让调试工具运行到整段程序组后一句,观察作用域的变化fun函数对象的scopes作用域链的变化。

image.png

image.png

image.png

image.png

  • 总结:函数作用域
  • 其实是js引擎在调用函数时才临时创建一个作用域对象。其中保存函数的局部变量。而函数调用完,函数作用域对像就释放了。