scope chain

一个函数有一个scope chain
函数每调用一次,该函数的scope上创建一个对象,函数的局部变量被当做属性赋值给这个新对象。
所以对嵌套函数

function A() {var a = 'A';function B() {var b = 'B'}function C() {var c = 'C'}
}

scope A <— scope B
^
|
|_ scope C
当A()被调用。 scope A上有新对象,新对象有a属性。
scope B上有新对象, 新对象有b属性。
scope C上有新对象, 新对象有c属性。
B函数内能通过scope chain找到a 属性
C函数也能通过scope chain找到a 属性,两者是同一对象。因为都是在A()的这次调用里新建的对象的a属性。

context上下文

阿里前端的一道题:

var Obj = function() {this.msg = 'ok';this.shout = function() {alert(this.msg)};this.waitAndShout = function() {//填写代码,5s后调用this.shout}
}

错误代码1:

setTimeout.call(this, this.shout, 1000)
// illegal invocation

错误代码2:

var f = setTimeout.bind(this)
f(this.shout , 1000)
// illegal invocation

正确代码:

setTimeout( this.shout.bind(this) , 1000)
// this.shout的context由window变为this

函数调用时,发生了什么

函数被调用时,将创建一个execution context,创建执行上下文时,发生了三件事:
1. 创建Activation object
2. 创建arguments 对象
3. 创建scope

这里我们主要关心scope, scope是a list( or a chain ) of objects. 每个函数对象都有一个[[scope]]属性,[[scope]]属性由对象序列or对象链表构成。这个列表/链表被[[scope]]属性引用,Activation object在列表/链表头。
接下来,初始化variables. 也是发生三件事:
1. 函数的参数会变成Activation object的属性。
2. 内部函数会变成Activation object的属性。
3. var 会变成Activation object的属性。

这些属性都会赋值为undefined,直到执行函数体里的赋值语句。这就是传说中的Hoisting, 预声明~

scope呢?先看原文:

Function objects created with the Function constructor always have a [[scope]] property referring to a scope chain that only contains the global object.
Function objects created with function declarations or function expressions have the scope chain of the execution context in which they are created assigned to their internal [[scope]] property.

通俗翻译一下:
1. 函数语句声明的函数,[[scope]]指向global object
2. 函数定义和函数表达式的声明的函数,[[scope]]指向他们执行上下文的[[scope]]

Identifier Resolution:
解析标识符时,沿着[[scope]]指向的scope chain找,第一项显然是Activition Object,里面包含了:参数,内部函数,内部变量。找不到标识付,再去第二项,也就是执行上下文的[[scope]]找。。。依次类推。

所以之前A中含B,C的栗子,B,C的[[scope]]都指向了A的[[scope]],A的scope chain第一项含有a, 所以B,C都找到a,且是同一个a。

网易的说法

网易主要讲了词法环境:
注意词法环境的outer是有静态分析确定的

ecma定义

函数表达式执行时,函数对象的scope被赋值为当前execution context,和之前的吻合。

javascript scope chain相关推荐

  1. 擒贼先擒王,简单谈一下JavaScript作用域链(Scope Chain)

    前言 我们都知道一个执行上下文的数据(变量.函数声明和函数的形参)作为属性存储在变量对象中,同时我们也应该知道变量对象在每次进入上下文时创建并填入初始值,值的更新出现在代码执行阶段.那么咱们专门讨论与 ...

  2. scope在c语言中什么意思,JavaScript scope作用域与this关键字

    作为一个程序员, 你可能早已经习惯于面向对象语言中指代当前对象的引用(或者指针), 如的c++中的this或者 python 中的self,当然具有OO属性( javascript 其实更多的是一种所 ...

  3. 作用域链(scope chain)和原型链(prototype chain)

    locate the object in the scope chain, then proceed up the object's prototype chain until the propert ...

  4. java scope是什么意思_Tutorial:Javascript中的作用域(scope)是什么?(一)(试用FIREBUG了解)...

    From Learn About the Ext JavaScript Library Summary: 本教程讲解了Javascript中的作用域(scope)几个要点和变量可见度(variable ...

  5. JavaScript 作用域(Scope)详解

    JavaScript 作用域(Scope)详解 先对需要用到的名词解释一下,再通过例子深入理解 一.什么是作用域(Scope) [[scope]]:每个javascript函数都是一个对象,对象中有些 ...

  6. [翻译]Keeping your JavaScript out of the global scope

    Source Website (翻译练手) 2017年12月15日 Keeping your JavaScript out of the global scope (and why you want ...

  7. 利用Javascript来创建Ubuntu Scope

    在先前的教程"在Ubuntu OS上创建一个dianping Scope (Qt JSON)",我们知道如何使用C++来在Ubuntu平台上开发一个Scope:我们也在文章"使用golang来设计我们 ...

  8. JavaScript学习笔记—— 4. 变量、作用域和内存问题

    ECMAScript变量可能包含两种不同数据类型的值:基本类型值和引用类型值,其中基本类型值是简单的数据段,而引用类型值指的是那些可能由多个值构成的对象: 对于5种基本类型数据:undefined, ...

  9. 聊一聊javascript执行上下文

    跟大家聊聊js的执行上下文 一,相关概念 EC : 执行上下文 ECS : 执行环境栈 VO : 变量对象 AO : 活动对象 scope chain :作用域链 二,执行上下文 javascript ...

  10. 关于Javascript的内存泄漏问题的整理稿

    常规循环引用内存泄漏和Closure内存泄漏 要了解javascript的内存泄漏问题,首先要了解的就是javascript的GC原理. 我记得原来在犀牛书<JavaScript: The De ...

最新文章

  1. linux缓存限制,如何限制复制使用的缓存,以便仍有其他缓存可用的内存?_linux_开发99编程知识库...
  2. linux 内核网络协议栈
  3. ASP.NET没有魔法——ASP.NET MVC 与数据库之MySQLEF
  4. python类与对象-如何为创建大量实例节省内存
  5. 计算机中那些事儿(九):资料管理一些建议---理论篇
  6. php表格批量修改数据,php批量修改数据库表名前缀
  7. 如何安装vscode网页版_如何让用编辑器编写EverNote?
  8. 【机器学习】一些模型的位置总结
  9. mysql学习资料_PHP程序员2020学习方向:高并发、性能调优、分布式、微服务...
  10. 自动驾驶 11-2: 激光雷达传感器模型和点云 LIDAR Sensor Models and Point Clouds
  11. goahead webserver源码分析
  12. 欧拉筛素数的应用-漂亮数
  13. 按键精灵 - 安卓版 - 罗盘 - 八向方位模拟 - 自动寻路
  14. A Density-Based Algorithmfor Discovering Clusters in LargeSpatial Databaseswith Noise(KDD-96)
  15. linux的帮助,帮助信息_Linux公社 - Linux系统门户网站
  16. ubuntu中显示实时网速的方法
  17. 据为己有!这位985博导把审稿的文章拒了,自己投!
  18. Qt(C++)中如何连接sqlite3数据库及如何使用
  19. vue使用iview中Upload上传组件
  20. C/C++中的void 和 void *

热门文章

  1. 非常规的DeepFaceLab(DeepFake)小花招和注意事项
  2. Mysql中select into from用法
  3. Word文档如何去掉最后一页的页码且不会影响其它页的页码
  4. JavaWeb项目启动时,自动执行指定方法
  5. chrome消除缓存的默认设置
  6. html如何发送语音,浏览器实现HTML5发送语音功能
  7. 在 ubuntu 的桌面上创建快捷方式
  8. caj文档如何免费转换成pdf格式
  9. Php生成图片的大小单位是cm,php生成图片缩略图代码类
  10. 梯度下降与支持向量机