码迷,mamicode.com
首页 > 编程语言 > 详细

javascript的地基

时间:2015-09-07 21:17:23      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:

有了良好的基础,才能在其上创造有价值的东西。

回顾一下以往自己javascript应用的开发经历,似乎很少去思考和总结js的运行机制。现在我就来整理整理

1. 以《编译原理》的一段话开头:

  传统的编译型语言,编译的过程是:词法分析、语法分析、语义检查、代码优化和字节生成;

  解释型语言,通过词法分析和语法分析后得到语法树,然后就可以开始解释执行了。

词法分析是将字符流转换为记号流。词法结构是一门语言的基础,词法分析又是另一个领域了。

eg:

  自然语言翻译来看,词法分析是一对一的硬性翻译,还很难理解,进一步翻译---》语法分析

  语法分析 --》 语法树  后可能还有模糊不清的地方 --》 语义检查(  对于传统强类型语言来讲,语义检查的主要部分是类型检查:

  函数的实参和形参的类型是否匹配  )

 

任何语言都有编译过程,只是解释型语言没有编译成二进制代码

 

2. js的作用域机制

词法作用域(静态作用域(with和eval除外)):js变量的作用域是在定义时决定而不是执行时决定。

js引擎在执行每个函数实例时,都会创建一个执行环境。执行环境中包含一个调用对象(call object),

调用对象是一个scriptObject结构,用来保存内部变量表varDecls、内嵌函数表funDecls、父级引用列表upvalue等语法分析结构(varDecls和funDecls等信息是在语法分析阶段就已经得到,并保存在语法树中的。函数实例执行时,会将这些信息从语法树复制到scriptObject)

词法作用域是js的作用域机制,它的实现方法就是作用域链。作用域链是一个name lookup机制,首先在当前执行环境的scriptObject中寻找,没找到,则顺着upvalue到父级scriptObject中寻找,一直lookup到全局调用对象。

当一个函数实例执行时,会创建或关联到一个闭包。scriptObject用来静态保存与函数相关的变量表,闭包则在执行期动态保存这些变量表及其运行值。

函数实例在活动引用为空后会自动销毁,闭包则要等要数据引用为空后,由JS引擎回收(有些情况下不会自动回收,就导致了内存泄漏)。

现在可以解释一下“预解析”:step2的语法分析阶段完成,并存储在语法树中。当执行到函数实例时,会将varDelcs和funcDecls从语法树中复制到执行环境的scriptObject上。

未定义变量意味着在scriptObject的变量表中找不到,JS引擎会沿着scriptObject的upvalue往上寻找,如果都没找到,对于写操作i = 1; 最后就会等价为 window.i = 1; 给window对象新增了一个属性。对于读操作,如果一直追溯到全局执行环境的scriptObject上都找不到,就会产生运行期错误。

 

javascript的地基

标签:

原文地址:http://www.cnblogs.com/youlanlan/p/4789895.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!