从函数作用域和块级作用域看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的作用域链的更多相关文章
- js的函数作用域跟块级作用域
js的函数作用域跟块级作用域(原文地址:http://blog.csdn.net/huangjq36sysu/article/details/51085674)
- Flask07 Jinja2模板测试器、控制语句IF/FOR、变量/块 赋值、作用域、块级作用域
1 测试器及其使用 在模板中的 {{}} 可以书写测试器,格式如下 {{ 变量 is 测试器名称 }} 1.1 在python中导入 Jinja2 的模板 from jinja2 import te ...
- JavaScript的作用域和块级作用域概念理解
作用域 作用域永远都是任何一门编程语言中的重中之重,因为它控制着变量与参数的可见性与生命周期.说到这里我们需要理解两个概念:块级作用域与函数作用域. 函数作用域 这个应该好理解,函数作用域就是说定义在 ...
- JavaScript 学习-变量的作用域和块级作用域
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 函数作用域和块级作用域--你不知道的JavaScript
et和const在{}内声明都会变为外部不能访问的值,但是const声明的是常量,也不能修改 函数是 JavaScript 中最常见的作用域单元.本质上,声明在一个函数内部的变量或函数会在所处的作用域 ...
- 匿名函数块级作用域以及在JQuery中的应用
最近经常回在群里面看到有些朋友问如下这样的js写法该如何理解的的问题,虽然可能对匿名函数有些理解,但是有时候看到JQuery源码或者其他JS库中同样的写法时,就有点不理解了,今天再次分享下这方面的知识 ...
- JavaScript 作用域 匿名函数 模仿块级作用域(私有作用域)
作用域 对于有块级作用域的语言来说,for语句中定义并初始化的变量i在循环外是无法访问的. 而javascript没有块级作用域,for语句中定义的变量i在循环结束后,依旧会存在于循环外部的执行环境( ...
- Javascript高级编程学习笔记(25)—— 函数表达式(3)模仿块级作用域
昨天写了闭包 今天就来聊聊块级作用域的事情 在绝大多数编程语言中,都有块级作用域这个概念 什么是块级作用域呢? 前面我们在刚开始讲的时候说过,JS中的大括号(不在赋值运算符的后面)表示代码块 块级作用 ...
- JavaScript模仿块级作用域
avaScript 没有块级作用域的概念.这意味着在块语句中定义的变量,实际上是在包含函数中而非语句中创建的,来看下面的例子: function outputNumbers(count){ for ( ...
随机推荐
- 类的互相包含------新标准c++程序设计
#include<iostream> using namespace std; class A; class B{ public: void f(A* pt){}; } class A{ ...
- UIImageView 动画
1.UIImageView 动画 1.1 播放图片集 @property (nonatomic, strong) UIImageView *playImageView; self.playImageV ...
- Mybatis注解开发
mybatis 的常用注解: @Insert:实现新增 @Update:实现更新 @Delete:实现删除 @Select:实现查询 @Result:实现结果集封装 @Results:可以与 @Res ...
- Linux磁盘占满 no space left on device
假如当前文件删除了,如果还有其他进程还在使用这个文件,这个文件删不干净:https://www.cnblogs.com/heyonggang/p/3644736.html 在Linux下查看磁盘空间使 ...
- 洛谷P2800 又上锁妖塔
放题解 题目传送门 放代码
- window环境下安装Python2和Python3
一. python 安装 1. 下载安装包 https://www.python.org/ftp/python/2.7.14/python-2.7.14.amd64.msi # 2.7安装包 htt ...
- Python面向对象之元类(metaclass)
点进来看就完事了铁汁!
- UVA - 11029 输出前三位
题意:给定\(a\)和\(n\),输出\(a^n\)的前三位和后三位 后三位快速幂 \(log_{10}(a^n)=n*log_{10}(a)=n*log_{10}(x*y),y<10,x mo ...
- Codeforces - 240F 是男人就上26棵线段树
#include<bits/stdc++.h> using namespace std; const int maxn = 1e5+11; typedef long long ll; ch ...
- 事件获取目标 currentTarget target srcElement 三者之间的区别和联系
currentTarget 指的是触发事件的当前对象,可以是冒泡和捕获的对象,不一定是点击或者鼠标移入等事件的直接触发对象.可以是他的父元素等. target 指的是事件触发的直接对象.IE有兼容 ...