js作用域超全介绍--全局作用域、局部作用、块级作用域

一、作用域定义

作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。在JavaScript中,变量的作用域有全局作用域和局部作用域两种。ES6中新增块级作用域。

相应作用域的变量分别称为全局变量、局部变量和块级变量。


二、全局作用域

一般来说以下几种情形拥有全局作用域:

(1)最外层函数和在最外层函数外面定义的变量拥有全局作用域,直接写在script标签中的JS代码或单独一个JS文件中的;

复制代码
<script>
  var a = 1;
</script>

(2)所有末定义直接赋值的变量自动声明为拥有全局作用域(情况较少);

(3)所有window对象的属性拥有全局作用域。一般情况下,window对象的内置属性都拥有全局作用域,例window.name、window.location、window.top等等。

复制代码
var a = 1;
function b(){
  console.log(a); // 1 a为全局变量可以在函数内访问到
}
console.log(a); // 1 可以全局访问
console.log(window.a); // 1 可以全局访问

三、局部作用域

1、 也称为函数作用域,其含义是指,属于这个函数的全部变量都可以在整个函数的范围内使用及复用(包括嵌套的作用域中也可以使用)在固定的代码片段才能被访问;

复制代码
function b(){
  var a = 1; // 变量a定义在函数内部
}
console.log(a) // error,引用错误,a没有定义

2、调用函数时创建函数作用域,函数执行完成后,函数作用域就销毁,每调用一次函数就会创建一个新的函数作用域,他们之间是互相独立的;

复制代码
function b(){
  if(true){
    var a = 1; // a的作用域不是if的范围,而是在函数中
  }
  console.log(a); // 1 在函数内部能访问到
}
console.log(a); // error引用错误

**3、和全局作用域的关系:**在函数作用域中可以访问到全局作用域的变量,但是在全局作用域中是访问不到函数作用域的变量;当函数作用域操作一个变量时,它会先在自身中寻找,如果有就直接使用,如果没有就向上一级作用域中寻找,直到找到全局作用域。

复制代码
var a = 1;
function b(){
  var a = 10;
  console.log(a); // 10 局部变量和全局变量同名,在函数作用域中,局部变量覆盖全局变量
}
console.log(a); // 1 输出全局变量的值

四、块级作用域

ES6 中引入了 let 与 const,与 var 不同的是在大括号(包括纯粹的大括号、if、while、for)间用var 定义的变量处在全局作用域。如果我们用 let 与 const 在大括号中定义,变量将处于块作用域。

复制代码
{
  var a = 1; // var声明a=1 全局变量
  let b = 2; // let声明b=2 局部变量
  const c = 3; // const声明c=3 局部变量
  console.log(a) // 1
  console.log(b) // 2
  console.log(c) // 3
}
console.log(a) // 1
console.log(b) // error引用错误,b未定义
console.log(c) // error引用错误,c未定义

对块级变量来说,其作用域是块级变量声明语句开始到块结束之间的区域。

let 与 const 的不同点在于,const 定义的是一个常量,无法修改定义后的值。

复制代码
{
  const a; // 语法错误,const声明必须初始化赋值
  const b = 1; // const声明c为常量,赋值后不会改变,在块级作用域内
}
console.log(b); // error引用错误b未定义

五、作用域中的特殊情况

1、函数参数------属于函数(局部)作用域

复制代码
function printAge(age) {
  console.log('我今年' + age + '岁了');
}
printAge(20); // 我今年20岁了
console.log(age); // 报错

2、for循环

使用var---全局作用域,外面也可以访问

复制代码
for(var i = 0; i < 10; i++) {
  console.log(i); // 0 1 2 3 4 5 6 7 8 9 
}
console.log(i); // 10

使用let---块级作用域,只能在{}范围内被访问,外面访问不到

复制代码
for(let i = 0; i < 10; i++) {
  console.log(i); // 0 1 2 3 4 5 6 7 8 9 
}
console.log(i); // error

3、try...catch中的err---不属于任何作用域,只能被catch访问

复制代码
try {
  throw new Error();
} catch (err) {
  var test = 'hello';
  const test2 = 'Hi';
  console.log(err); // 正常打印
}
console.log(test); // hello
console.log(test2); // 报错
console.log(err); // 报错

六、作用域实例

复制代码
function Person() {
  getAge = function () {
    console.log(1);
  }
  return this;
}

Person.getAge = function () {
  console.log(2);
}

Person.prototype.getAge = function () {
  console.log(3);
}

var getAge = function () {
  console.log(4);
}

function getAge() {
  console.log(5);
}

Person.getAge();
getAge();
Person().getAge();
getAge();
new Person.getAge();
new Person().getAge();

输出结果:2 4 1 1 2 3

相关推荐
半点寒12W1 小时前
微信小程序实现路由拦截的方法
前端
某公司摸鱼前端2 小时前
uniapp socket 封装 (可拿去直接用)
前端·javascript·websocket·uni-app
要加油哦~2 小时前
vue | 插件 | 移动文件的插件 —— move-file-cli 插件 的安装与使用
前端·javascript·vue.js
小林学习编程2 小时前
Springboot + vue + uni-app小程序web端全套家具商场
前端·vue.js·spring boot
柳鲲鹏2 小时前
WINDOWS最快布署WEB服务器:apache2
服务器·前端·windows
weixin-a153003083163 小时前
【playwright篇】教程(十七)[html元素知识]
java·前端·html
ai小鬼头4 小时前
AIStarter最新版怎么卸载AI项目?一键删除操作指南(附路径设置技巧)
前端·后端·github
wen's4 小时前
React Native 0.79.4 中 [RCTView setColor:] 崩溃问题完整解决方案
javascript·react native·react.js
一只叫煤球的猫4 小时前
普通程序员,从开发到管理岗,为什么我越升职越痛苦?
前端·后端·全栈
vvilkim4 小时前
Electron 自动更新机制详解:实现无缝应用升级
前端·javascript·electron