Lambda博客
  • 自我介绍
  • SSR
    • 浅谈SSR
  • React
    • 页面路由——React-Router
    • 管好你的状态——React-Redux
    • 一个哪行——React详解
    • 左膀右臂一个不少——React初探
  • 问题记录
    • js-xlsx实现纯前端导出excel表格
    • 前端开发需要了解的东西
    • 打造高性能网站
  • JavaScript学习笔记
    • 语法和API
    • js-垃圾回收
    • 收集的JS使用技巧
    • 执行机制
    • 原型和原型链
    • 执行上下文
    • 事件循环
    • JavaScript手写代码
    • 43道JS面试题
    • 悄悄的带走了你的东西——闭包详解
    • 你是个富二代吗?——JavaScript作用域链
    • 捉摸不透的女生——JavaScript类型转换
    • 这是你的女神!——JavaScript
  • 网络学习笔记
    • 强不强——HTTP-协商缓存VS强缓存
    • 网络缓存
    • 我要飞的更高——计算机网络
    • 快点!再快点!——CDN
    • 喜怒哀乐多状态——HTTP状态码
    • 你会爱上我的(ಥ_ಥ) ——TCP详解
    • 隔壁老王想篡位?门都没有——同源策略
  • 软技能
  • 安全专题
    • 保护好自己——网站安全,预防
  • 浏览器兼容性
    • 我是个好人——浏览器兼容性
  • 多图片加载——懒加载详解
  • 数据结构
  • Node
    • Node初探
  • Typescript
    • JS Plus 真香——初探 TypeScript
  • 设计模式
    • 不要花里胡哨,要一套一套——设计模式(1)
    • 学会“套路”——设计模式(2)
  • Vue
    • 实操实干——vue实例记录
    • 停下来,问问自己——Vue-刨根问底
    • 你有喘息的机会吗?——Vue,逐步了解
    • 你累吗?来来来,安利框架——Vue-初次见面
  • 小程序
    • 今天天气怎么样——记一次小程序开发
  • Webpack
    • 蛋糕分割整合工具——Webpack-前端工程化
  • 你一块,我一块——Web-modules 前端模块化
  • HTML5
    • 你会画小猪佩奇吗?—— canvas
    • 画个矢量图——HTML5-SVG
    • 听说你爱闹腾——HTML5-多媒体
    • 动画神器——HTML5-requestAnimationFrame
    • 留下痕迹——HTML5-客户端存储
    • 你知道指北针吗?——HTML5-DeviceMotionEvent
    • 你在哪啊?我在这啊——HTML5-Geolocation
    • 你到这,你到那——HTML5-拖拽
    • 你从这,到那——HTML5-拖拽上传文件
    • 开启前端之路——HTML 标签
  • 瀑布流(无限滚动)
  • 我是怎么来的?——浏览器渲染原理
  • Css
    • 由大变小,你行吗 —— 移动端
    • 动起来,这样比较炫—— CSS3 动画
    • 请不要拐弯抹角 —— CSS3 选择器
    • 想炫吗?—— CSS3 属性
    • 最后的最后——CSS自问自答
    • 万事开头难?——深入学习前端常见布局
    • 一入前端深似海——BFC剖析
    • 还有哪些好玩的东西——CSS提升
    • 那些好看的页面是怎么形成的——CSS 初识
  • 拿个小本本记下——Cookie
由 GitBook 提供支持
在本页
  • 理解词法作用域和动态作用域
  • 理解 JavaScript 的作用域和作用域链
  • 理解 JavaScript 的执行上下文栈,可以应用堆栈信息快速定位问题
  • this 的原理以及几种不同使用场景的取值
在GitHub上编辑
  1. JavaScript学习笔记

你是个富二代吗?——JavaScript作用域链

理解词法作用域和动态作用域

作用域

作用域是指程序源代码中定义变量的区域。 作用域规定了如何查找变量,也就是确定当前执行代码对变量的访问权限。 JavaScript 采用词法作用域(lexical scoping),也就是静态作用域。

静态作用域与动态作用域

因为 JavaScript 采用的是词法作用域,函数的作用域在函数定义的时候就决定了,而词法作用域相对的是动态作用域,函数的作用域是在函数调用的时候才决定的。

理解 JavaScript 的作用域和作用域链

什么是作用域?

作用域是在运行时代码中的某些特定部分中变量,函数和对象的可访问性。换句话说,作用于决定了代码区块中变量和其他资源的可见性。 作用域就是一个独立的地盘,让变量不会外泄,暴露出去。 作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突。 ES6 之前 JavaScript 没有块级作用域,只有全局作用域和函数作用域。ES6 的到来,为我们提供了’块级作用域’,可通过新增命令 let 和 const 来体现。

  • 全局作用域和函数作用域

    • 最外层函数和最外层函数外面定义的变量拥有全局作用域

    • 所有未定义直接赋值的变量自动声明为拥有全局作用域

    • 所有 window 对象的属性拥有全局作用域

全局作用域有个弊端:如果我们写了很多 JS 代码,变量定义都没有用函数包括,那么他们就全部都在全局作用域中。这样就会污染全局命名空间,容易引起命名冲突。

作用域是分层的,内层作用域可以访问外层作用域的变量,反之则不行。

值得注意的是:块语句(大括号”{}”中间的语句), 如 if 和 switch 条件语句或 for 和 while 循环语句,不像函数,它们不会创建一个新的作用域。

  • 块级作用域

    • 在一个函数内部创建

    • 在一个代码块(由一对花括号包裹)内部

  • 块级作用域有以下几个特点

    • 声明变量不会提升到代码块顶部

    • 禁止重复声明

    • 循环中的绑定块作用域

作用域链

作用域中所存储的执行期上下文对象的集合,这个集合呈链式链接,我们把这种链式链接叫做作用域链。

理解 JavaScript 的执行上下文栈,可以应用堆栈信息快速定位问题

什么是执行上下文?

简而言之,执行上下文是评估和执行 JavaScript 代码的环境的抽象概念。 每当 JavaScript 代码运行的时候,它都是在执行上下文中运行。

执行上下文类型

  • JavaScript 中有三种执行上下文类型

    • 全局执行上下文

      • 这是默认或者说基础的上下文,任何不在函数内部的代码都在全局上下文中。它会执行两件事:创建一个全局的 window 对象(浏览器的情况下),并且设置this的值等于这个全局对象。一个程序中会有一个全局执行上下文。

    • 函数执行上下文

      • 每当一个函数被调用时,都会为该函数创建一个新的上下文。每个函数都有它自己的执行上下文,不过是在函数被调用时创建的。函数上下文可以有任意多个。每当一个新的执行上下文被创建,它会按定义的顺序执行一系列步骤。

    • Eval 函数执行上下文

      • 执行在 eval 函数内部的代码也会有它属于自己的执行上下文。

运行期上下文

当函数执行时,会创建一个称为执行器上下文的内部对象,一个执行期上下文定义了一个函数执行时的环境,函数每次执行时对应的执行上下文都是独一无二的,所以多次调用一个函数会导致创建多个执行上下文,当函数执行完毕,它所产生的执行上下文被销毁。

this 的原理以及几种不同使用场景的取值

JavaScript 中 this 含义完全取决于函数调用方式

  • JavaScript 中函数的调用有以下几种方式

    • 作为对象方法调用

    • 作为函数调用

    • 作为构造函数调用

    • 使用 apply 或 call 调用

作为对象调用

在 JavaScript 中,函数也是对象,因此函数可以作为一个对象的属性,此时该函数被称为该对象的方法,this 被自然绑定到该对象。

作为函数调用

函数也可以直接被调用,此时 this 绑定到全局对象。在浏览器中,window 就是该全局对象。

作为构造函数调用

JavaScript 支持面向对象式编程,不过 JavaScript 并没有类(class)的概念,而是使用基于原型(prototype)的继承方式。【构造函数以大写字母开头】。 在内部函数中,即声明在另外一个函数体内的函数,这种绑定到全局对象的的方式会产生另外一个问题。我们需要在内部函数中创建变量存下外部函数的 this,该变量一般命名为 that。

在 call 或者 apply 中调用

他们允许切换函数执行上下文环境(context),即 this 绑定的对象。

上一页悄悄的带走了你的东西——闭包详解下一页捉摸不透的女生——JavaScript类型转换

最后更新于3年前

深入理解 JavaScript 执行上下文、函数堆栈、提升的概念