深入理解JavaScript系列学习笔记——关于变量

通常,各类文章和JavaScript相关的书籍都声称:“不管是使用var关键字(在全局上下文)还是不使用var关键字(在任何地方),都可以声明一个变量”。请记住,这是错误的概念:
任何时候,变量只能通过使用var关键字才能声明。

1.全局对象的属性

下面的赋值语句:

a = 10;

这仅仅是给全局对象创建了一个新属性(但它不是变量)。“不是变量”并不是说它不能被改变,而是指它不符合ECMAScript规范中的变量概念,所以它“不是变量”(它之所以能成为全局对象的属性,完全是因为VO(globalContext) === global,大家还记得这个吧?)。
让我们通过下面的实例看看具体的区别吧:

alert(a); // undefined
alert(b); // "b" 没有声明

b = 10;
var a = 20;
所有根源仍然是VO和进入上下文阶段和代码执行阶段:
进入上下文阶段:
VO = {
  a: undefined
};

我们可以看到,因为“b”不是一个变量,所以在这个阶段根本就没有“b”,“b”将只在代码执行阶段才会出现(但是在我们这个例子里,还没有到那就已经出错了)。
让我们改变一下例子代码:

alert(a); // undefined, 这个大家都知道,

b = 10;
alert(b); // 10, 代码执行阶段创建

var a = 20;
alert(a); // 20, 代码执行阶段修改

2.delete属性

关于变量,还有一个重要的知识点。变量相对于简单属性来说,变量有一个特性(attribute):{DontDelete},这个特性的含义就是不能用delete操作符直接删除变量属性。

a = 10;
alert(window.a); // 10

alert(delete a); // true

alert(window.a); // undefined

var b = 20;
alert(window.b); // 20

alert(delete b); // false

alert(window.b); // still 20
但是这个规则在有个上下文里不起走样,那就是eval上下文,变量没有{DontDelete}特性。
eval('var a = 10;');
alert(window.a); // 10

alert(delete a); // true

alert(window.a); // undefined

3.活动对象的访问

特殊实现: _parent_ 属性
前面已经提到过,按标准规范,活动对象是不可能被直接访问到的。但是,一些具体实现并没有完全遵守这个规定,例如SpiderMonkey和Rhino;的实现中,函数有一个特殊的属性 parent,通过这个属性可以直接引用到活动对象(或全局变量对象),在此对象里创建了函数。
例如 (SpiderMonkey, Rhino):

var global = this;
var a = 10;

function foo() {}

alert(foo.__parent__); // global

var VO = foo.__parent__;

alert(VO.a); // 10
alert(VO === global); // true

在上面的例子中我们可以看到,函数foo是在全局上下文中创建的,所以属性parent 指向全局上下文的变量对象,即全局对象。
然而,在SpiderMonkey中用同样的方式访问活动对象是不可能的:在不同版本的SpiderMonkey中,内部函数的parent 有时指向null ,有时指向全局对象。
在Rhino中,用同样的方式访问活动对象是完全可以的。
例如 (Rhino):

var global = this;
var x = 10;

(function foo() {

  var y = 20;

  // "foo"上下文里的活动对象
  var AO = (function () {}).__parent__;

  print(AO.y); // 20

  // 当前活动对象的__parent__ 是已经存在的全局对象
  // 变量对象的特殊链形成了
  // 所以我们叫做作用域链
  print(AO.__parent__ === global); // true

  print(AO.__parent__.x); // 10

})();

本文整理摘录自:汤姆大叔的博客—— 深入理解JavaScript系列(12):变量对象(Variable Object)

猜你喜欢

转载自blog.csdn.net/yangyuqingabc/article/details/80767249