Skip to content

关于 var、let 的顶层对象的属性 #221

@tofrankie

Description

@tofrankie

顶层对象 ,在浏览器环境指的是 window 对象,在 Node 指的是 global 对象。ES5 之中,顶层对象的属性与全局变量是等价的。

window.a = 1;
console.log(a);  // 1

a = 2;
console.log(window.a);  // 2

在上面代码中,顶级对象的属性赋值与全局变量的赋值,是同一件事。

顶层对象的属性与全局变量挂钩,被认为是 JavaScript 语言最大的设计败笔之一。这样的设计带来了几个很大的问题,首先是没法在编译时就报出变量未声明的错误,只有运行时才能知道(因为全局变量可能是顶层对象的属性创造的,而属性的创造是动态的);其次,程序员很容易不知不觉地就创建了全局变量(比如打字出错);最后,顶层对象的属性是到处可以读写的,这非常不利于模块化编程。另一方面,window 对象有实体含义,指的是浏览器的窗口对象,顶层对象是一个有实体含义的对象,也是不合适的。

ES6 为了改变这一点,一方面规定,为了保持兼容性,varfunction 声明的全局变量,依旧是顶层对象的属性;另一方面规定,letconstclass 声明的全局变量,不属于顶层对象的属性。也就是说,从 ES6 开始,全局变量将逐步与顶层对象的属性脱钩。

var a = 1;
// 如果在 Node 的 REPL 环境,可以写成 global.a
// 或者采用通用方法,写成 this.a
console.log(window.a);  // 1
console.log(this.a);    // 1

let b = 1;
console.log(window.b);  // undefined
console.log(this.b);    // undefined

上面代码中,全局变量 avar 命令声明,所以它是顶层对象的属性;全局变量 blet 命令声明,所以它不是顶层对象的属性,返回 undefined

Metadata

Metadata

Assignees

No one assigned

    Labels

    20202020 年撰写JS与 JavaScript、ECMAScript 相关的文章

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions