专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »Javascript教程 » 作用域:再探Javascript词法作用域 »正文

作用域:再探Javascript词法作用域

来源: 发布时间:星期四, 2009年3月19日 浏览:0次 评论:0


写在前面话:每个人都会犯错——有时候‘孰能无过过而能改善莫大焉’有时候知道自己错了却没有机会更改其实错了并不仅仅是错了做错了除了及时改正和弥补的外最重要是为自己犯错承担所有责任

2009年3月14日我去参加网易互动专场招聘会应聘网页工程师职位有幸参加笔试然后有幸栽在笔试呵呵废话少说抓出音响极深题重新研究研究

题目大概是:写出如下代码输出结果并进行分析

var tt = 'aa';
function test{
alert(tt);
var tt = 'dd';
alert(tt);
}
test;
“太简单了!”这是我当时看到这个题目是想法于是轻率答题竟成我致命的伤答案是——aa和dd解析:第次输出全局变量结果然后局部变量tt覆盖全局变量所引用所以第 2次输出结果是dd

任何人见我如此作答都会认为我是在扫盲——想法及其幼稚(我也这么认为)!

网易啊如何可能会满意于这种答案!

正确答案应该是:und和dd

为什么第次alert结果是und呢?要解释得清楚明白需要用到Javascript词法作用域

Javascript中“在定义它们作用域里运行而不是在执行它们作用域里运行”这是权威指南里抽象而精辟整理总结

Javascript逻辑默认在个全局作用域中执行如以上段中“var tt='aa';”就是定义个全局作用域全局变量(如果以上代码段不是摘自某个话)而test内部逻辑必须在原有作用域(全局作用域)链再添加test本身作用域(局部性)——这些思想几乎在每种语言中都是如此定义然而Javascript作用域链特别的处在于内部能够嵌套定义(这是闭包基础注:在JS中是唯形式代码作用域)

嵌套内部可以外部(被嵌套)变量和其他嵌套(种数据)如果是在外部嵌套那么对象不变当外部执行完毕后所有数据(包括外部和嵌套内部)都将被垃圾回收机制收集——这点还不能体现出‘闭包’精华种情况就是Javascript允许外部嵌套内部即使被嵌套已经被‘垃圾收集’——最常见就是在‘某个’中用其嵌套内部定义某些元素响应事件页面载入时候被嵌套(‘某个’)已经执行完毕(被垃圾回收)但当事件触发时候仍然会有响应动作而且响应中还可能到在被嵌套(‘某个’)中定义变量最终值(不是被垃圾回收了吗?)

有关闭包知识和举例有很多资料可供查询我不想叙述

本文重点是以下非常重要细节:

对象位于作用域链前端局部变量(在内部用var声明变量)、参数及Arguments对象都在作用域中——这意味着它们隐藏了作用域链更上层任何同名属性

在以上片段中test内部“var tt='dd'”将会致使“var tt='aa'”在test时完全被隐藏而且tt是在第个alert语句的后定义所以在到第个alert时tt是还没有被赋值这样说可能会清楚在定义test当定义第个alert(tt)时这里会记录tt是作用域链中个变量但不会记录它(tt)定义完毕后tt就添加到作用域里所以第个alert语句能够找到该作用域里tt(即相当于找到个已经在内部声明但未被赋值tt)

以上片段执行结果和以下片段结果相同:

var tt = 'aa';
function test{
var tt;
alert(tt);
tt = 'dd';
alert(tt);
}
test;
Javascript作用域不可简单用C等语言思维来理解啊!C的前必须先声明或定义而Javascript没必要在Javascript中可以先后再定义(不用在的前作任何声明)Javascript是向作用域链要定义(在定义它们作用域里运行而不是在执行它们作用域里运行)

如以上代码写成:

var tt = 'aa';
test; //先后再定义
function test{
alert(tt); //und
var tt = 'dd';
alert(tt); //dd
}
以上代码片段虽然能够得到相同结果但最好不要那样写啦习惯不好代码不好维护



重申下本文重点:

在定义它们作用域里运行而不是在执行它们作用域里运行

对象位于作用域链前端局部变量(在内部用var声明变量)、参数及Arguments对象都在作用域中——这意味着它们隐藏了作用域链更上层任何同名属性
0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: