通过函数作用域和块级作用域看javascript的作用域链

 更新时间:2018年08月05日 11:06:52   作者:余大彬  
这篇文章给大家分享了通过函数作用域和块级作用域看javascript的作用域链的相关知识点内容,有兴趣的朋友参考学习下。

在ES6之前,javascript只有全局作用域和函数作用域。所谓作用域就是一个变量定义并能够被访问到的范围。也就是说如果一个变量定义在全局(window)上,那么在任何地方都能访问到这个变量,如果这个变量定义在函数内部,那么就只能在函数内部访问到这个变量。

全局作用域只要页面没关闭就会一直存在,而函数作用域只有在函数执行的时候才存在,执行完就销毁。且每次执行函数都会创建一个新的作用域。

那么什么是作用域链呢?
在了解作用域链之前,我们先了解一个执行期上下文的概念。

执行期上下文:当函数执行时,会创建一个称为执行期上下文的内部对象(即AO或GO),一个执行期上下文定义了一个函数的执行环境,函数每次执行时对应的执行期上下文都是独一无二的,所以每次调用一个函数都会创建一个新的执行期上下文,当函数执行完毕,所产生的执行期上下文被销毁。

作用域链就是函数中[[scope]]属性所存储的执行期上下文对象的集合,这个集合呈链式链接,我们把这种链式链接叫做作用域链。

作用域链更像是一种包含的关系。比如说函数A内部定义了一个函数B,所以B的定义是依赖于A的,也就是说B在A的内部,那么B中就可以访问A的中的变量和方法。这种一层一层向上依赖的关系就构成了作用域链。

为了更好理解,我们直接看例子。

var name = 'xiaoyu';
function fn1() {};
function fn2() {
 var num = 10;
 function fn3() {
  var num1 = 10;
  console.log(num);
 };
 return fn3;
}
var fn4 = fn2();

在上个例子我们知道,fn2执行的时候返回fn3,产生了闭包。但是一个函数执行然后返回另一个函数都会产生闭包嘛?我们来看一下。

var name = 'xiaoyu';
function fn1() {};
function fn2() {
 var num = 10;
 function fn3() {//fn3函数没有依赖fn2函数内的变量
  var num1 = 10;
  console.log(num1);
 };
 return fn3;
}
var fn4 = fn2();

了解了作用域链之后,我们来看一个小例子,巩固一下。

var age = 10;
var obj = {
 age: 12,
 test: function() {
  console.log(age);
  console.log(obj.age);
  console.log(this.age);
 }
}
obj.test();

console.log(this.age)打印出12不难理解,但是为什么console.log(age)不也应该打印出12嘛。

我们说test执行时首先会在自己的作用域内查看有没有age变量,然后再沿着作用域链往上到全局作用域查找age变量,全局作用域下有age变量和data变量。所以console.log(age)打印出的10,如果要打印出12则需要访问obj.age。

ES6的块级作用域

在ES6之后,通过let和const引入了块级作用域。即通过let和const声明的变量只在声明所在的块级作用域内有效,并且let声明的变量虽然属于全局变量,但不再属于全局对象window。

我们通过一段代码来看一下引入块级作用域后,函数的作用域链的变化。

var age = 10;
let obj = {
 age: 12,
 test: function() {
   console.log(age);
   console.log(obj.age);
   console.log(this.age);
 }
}
obj.test();

相关文章

  • JavaScript Typescript基础使用教程

    JavaScript Typescript基础使用教程

    TypeScript是Microsoft(微软)开发的一种开源编程语言,它充分利用了JavaScript原有的对象模型,并在此基础上进行了扩充,TypeScript设计目标是开发大型应用,它可以编译成纯JavaScript,编译出来的JavaScript可以运行在任何一种JS运行环境中
    2022-12-12
  • JavaScript axios安装与封装案例详解

    JavaScript axios安装与封装案例详解

    这篇文章主要介绍了JavaScript axios安装与封装案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • IE6不能修改NAME问题的解决方法

    IE6不能修改NAME问题的解决方法

    昨天在项目中发现IE6动态生成的INPUT是不能改NAME的,微软关于这个问题有这么个说法
    2010-09-09
  • JS location几个方法小姐

    JS location几个方法小姐

    整理下面的方法,利用使用js获取url参数的朋友
    2008-07-07
  • Javascript闭包实例详解

    Javascript闭包实例详解

    闭包就是函数的局部变量集合,只是这些局部变量在函数返回后会继续存在,本文通过代码实例给大家介绍javascript闭包,对javascipt闭包相关知识感兴趣的朋友一起学习吧
    2015-11-11
  • JS代码混淆初步

    JS代码混淆初步

    JS代码混淆初步...
    2006-09-09
  • JS中跳转传参的几种常用方法总结

    JS中跳转传参的几种常用方法总结

    在前端开发中我们常常需要从一个跳到另一个页面,并且将当前页面的数据传递过去,下面这篇文章主要给大家总结介绍了关于JS中跳转传参的几种常用方法,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-05-05
  • JavaScript中Number对象的toFixed() 方法详解

    JavaScript中Number对象的toFixed() 方法详解

    下面小编就为大家带来一篇JavaScript中Number对象的toFixed() 方法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • javascript布局查看器效果代码

    javascript布局查看器效果代码

    用js直接区分网页布局代码,大家可以看下他的原理
    2008-10-10
  • 深入理解Javascript动态方法调用与参数修改的问题

    深入理解Javascript动态方法调用与参数修改的问题

    这篇文章主要是对Javascript动态方法调用与参数修改的问题进行了详细的分析介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2013-12-12

最新评论