javascript的词法作用域
副标题[/!--empirenews.page--]
大家应该写过下面类似的代码吧,其实这里我想要表达的是有时候一个方法定义的地方和使用的地方会相隔十万八千里,那方法执行时,它能访问哪些变量,不能访问哪些变量,这个怎么判断呢?这个就是我们这次需要分析的问题——词法作用域 var classA = function(){ this.prop1 = 1; } classA.prototype.func1 = function(){ var that = this, var1 = 2; function a(){ return function(){ alert(var1); alert(this.prop1); }.apply(that); }; a(); } var objA = new ClassA(); objA.func1(); 词法作用域:变量的作用域是在定义时决定而不是执行时决定,也就是说词法作用域取决于源码,通过静态分析就能确定,因此词法作用域也叫做静态作用域。 with和eval除外,所以只能说JS的作用域机制非常接近词法作用域(Lexical scope)。 下面通过几个小小的案例,开始深入的了解对理解词法作用域和闭包必不可少的,JS执行时底层的一些概念和理论知识。 经典案列重现1、经典案例一/*全局(window)域下的一段代码*/ function a(i) { var i; alert(i); }; a(10); 疑问:上面的代码会输出什么呢?
思考:局部变量 i 和形参 i 是同一个存储空间吗? 2、经典案例二/*全局(window)域下的一段代码*/ function a(i) { alert(i); alert(arguments[0]); //arguments[0]应该就是形参 i var i = 2; alert(i); alert(arguments[0]); }; a(10); 疑问:上面的代码又会输出什么呢?(( 10,10,2,10 || 10,10,2,2 ))
思考:这里能说明局部变量 i 和形参 i 的值相同吗? 3、经典案例三/*全局(window)域下的一段代码*/ function a(i) { var i = i; alert(i); }; a(10); 疑问:上面的代码又又会输出什么呢?(( undefined || 10 ))
思考:结合案列二,这里基本能说明局部变量 i 和形参 i 指向了同一个存储地址! 4、经典案例四/*全局(window)域下的一段代码*/ var i=10; function a() { alert(i); var i = 2; alert(i); }; a(); 疑问:上面的代码又会输出什么呢?(小子,看这回整不死你!哇哈哈,就不给你选项)
思考:到底怎么回事儿? 5、经典案例五…………..N看到上面的几个例子,你可能会想,怎么可能,我写了几年的 js 了,怎么这么简单例子也会犹豫,结果可能还答错了。其实可能原因是:我们能很快的写出一个方法,但到底方法内部是怎么执行的呢?执行的细节又是怎么样的呢?你可能没有进行过深入的学习和了解。要了解这些细节,那就需要了解 JS 引擎的工作方式,所以下面我们就把 JS 引擎对一个方法的解析过程进行一个稍微深入一些的介绍 代码解析过程1、javascript执行顺序编译型语言,编译步骤分为:词法分析、语法分析、语义检查、代码优化和字节生成。
2、特殊说明全局域(window)域下所有JS代码可以被看成是一个“匿名方法“,它会被自动执行,而此“匿名方法“内的其它方法则是在被显示调用的时候才被执行 3、关键步骤上面的过程,我们主要是分成两个阶段 javascript解析:就是通过语法分析和预解析构造合法的语法分析树。 3、关键概念到这里,我们再更强调以下一些概念,这些概念都会在下面用一个一个的实体来表示,便于大家理解 语法分析树(SyntaxTree):可以直观地表示出这段代码的相关信息,具体的实现就是JS引擎创建了一些表,用来记录每个方法内的变量集(variables),方法集(functions)和作用域(scope)等。 执行环境(ExecutionContext):可理解为一个记录当前执行的方法【外部描述信息】的对象,记录所执行方法的类型,名称,参数和活动对象(activeObject)。 (编辑:威海站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |