前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >理解JavaScript作用域和作用域链

理解JavaScript作用域和作用域链

原创
作者头像
用户10562852
发布2023-05-21 17:29:49
3780
发布2023-05-21 17:29:49
举报
文章被收录于专栏:前端不难前端不难

​一、JavaScript中的作用域

作用域是当前的执行上下文,值和表达式在其中“可见”或可被访问。如果一个变量或表达式不在当前的作用域中,那么它是不可用的。

代码语言:javascript
复制
function foo() {
	var x = 'sfa'
}
console.log(x) //  x is not defined

全局作用域和函数作用域

全局作用域:在JavaScript中 {} 外面的作用域就是全局作用域,里面的变量和函数等其他资源可以在任意地方被访问到。一般来说以下几种情况拥有全局作用域

  • 最外层函数和在最外层函数外面定义的变量
代码语言:javascript
复制
// 该函数和该变量供全局使用,foo函数内部依旧能够使用foo函数(此处未演示)
var a = 23;
function foo() {
    var b = 1;
    function inner() { // 内部函数不能被全局使用
		return false
	}
}
console.log(a, foo) // 23 [Function: foo] 
console.log(b) // b is not defined
 // console.log(inner) // inner is not defined
  • 不使用var声明直接赋值的变量

因为JavaScript在执行是会自动隐式地创建该全局变量

代码语言:javascript
复制
// 相当于在全局:var b;
function foo() {
    b = 1;
}
foo()
console.log(b) // 1
  • 全局对象(globalThis)

全局对象可以通过globalThis获取,浏览器环境中指 Window

代码语言:javascript
复制
console.log(globalThis) // Node 环境中
Object [global] {
  global: [Circular *1],
  clearInterval: [Function: clearInterval],
  clearTimeout: [Function: clearTimeout],
  setInterval: [Function: setInterval],
  setTimeout: [Function: setTimeout] {
    [Symbol(nodejs.util.promisify.custom)]: [Getter]
  },
  queueMicrotask: [Function: queueMicrotask],
  performance: Performance {
    nodeTiming: PerformanceNodeTiming {
      name: 'node',
      entryType: 'node',
      startTime: 0,
      duration: 43.25670003890991,
      nodeStart: 0.508400022983551,
      v8Start: 1.6218000054359436,
      bootstrapComplete: 33.73820000886917,
      environment: 12.502800047397614,
      loopStart: -1,
      loopExit: -1,
      idleTime: 0
    },
    timeOrigin: 1683861064321.689
  },
  clearImmediate: [Function: clearImmediate],
  setImmediate: [Function: setImmediate] {
    [Symbol(nodejs.util.promisify.custom)]: [Getter]
  }
}

函数作用域:在函数内部定义的变量、函数和其他资源。在这个作用域内声明的变量,就只能在它这个作用域和其子作用域中才能使用。

块级作用域

ES6新增的块级作用域:用let和const声明的变量才存在块级作用域,在该代码块外部访问不到该变量。在{ }中用let和const声明的变量就是一个块级作用域。

代码语言:javascript
复制
{
	let a = 1;
	console.log(a) // 1
}
console.log(a) // a is not defined 外部访问不到

二、作用域链

作用域链指的是各个作用域的嵌套关系和查找机制。

代码语言:javascript
复制
function foo() {
	var b = 'foo中的b'
    function bar() {
		// 当前作用域中没有声明b则查找上一级作用域(创建该作用域的那个域),依次类推,直至到全局作用域
		return b
	}
	return bar()
}

console.log(foo()) // foo中的b

上面代码中的b就是一个自由变量,即在当前作用域中没有定义b

三、js中的执行上下文

执行上下文(简称上下文)我们可以理解成一个js代码执行的环境,在代码执行阶段被创建,里面包含了定义的所有变量、函数以及this指向等。每个上下文都有一个关联的变量对象,保存着上面说的那些数据。虽然无法通过代码访问,但是后台处理数据会用到它。

全局上下文是最外层的上下文,表示全局上下文的对象可能不一样,在浏览器中就是 window 对象;上下文在其所有代码都执行完毕后会销毁(全局上下文在应用程序退出前被销毁)。

上下文中的代码在执行的时候会创建变量对象的一个作用域链(scope chain)。

希望本篇文章能够帮助到大家!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 全局作用域和函数作用域
  • 块级作用域
  • 二、作用域链
  • 三、js中的执行上下文
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档