JavaScript 的常见“陷阱”

495 查看

PHP是我的第一门编程语言,之后通过像jQuery这样的库首次接触JavaScript。由于JavaScript与PHP的工作原理不同,开始时总有一些JavaScript问题困扰着我。即使现在,仍有让我感到疑惑的东西。我想分享一些开始使用JavaScript时我苦苦思考的问题。这些问题将涉及:全局命名空间、this、ECMAScript 3 和ECMAScript 5的区别、异步调用、原型以及 简单的JavaScript继承。

全局命名空间

在PHP中,特别地,当你在类(或命名空间块)之外声明一个函数变量时,你实质上往全局命名空间添加了一个函数。在JavaScript中,没有所谓的命名空间,然而所有的东西都附属于全局对象。在Web浏览器中,全局对象就是windows对象。另一个主要区别是:在JavaScript中,函数和变量均是全局对象的属性,即我们通常指代的properties。

因为,当你覆盖一个全局函数或属性,JavaScript不会给出任何警告,所以这会很麻烦,实际上是相当危险的。

JavaScript中的一种技术是立即执行函数表达式,一般称为自执行匿名函数。它对于保持变量和函数的独立性是非常有用的。通常,我通过传入对象方式将函数暴露给外界。这是模块模式的一个变种。

在自执行匿名函数里,所有的全局作用域是封闭的,通过将之依附到module变量实现。从技术上讲,你可以直接把属性附加到module变量,但我们将它传递给函数的原因是:明确地表明函数所附加的地方。它允许我们给传入函数的对象起别名。这里的关键是:我们预先声明依赖于模块变量,而不依赖于全局变量。

你也许已经注意到了var关键字。如果你不知道如何使用它,基本的解释是:在声明变量前使用var,为离之最近的函数创建了一个属性。如果省略var关键字,那么意味着给现有变量分配一个新值,并提升了作用域链。这个作用域链可能是全局范围的。

正如你所看到的一样,在你的函数中依赖全局变量是相当危险的,因为可能产生副作用,造成难以预料的冲突。当你使用var关键字时,会发生什么呢?

JavaScript将var声明变量提升到函数块顶部,接着初始化变量。这就是所谓的变量提升

总结:所有变量的作用于一个函数内(函数本身就是一个对象),并使用var声明这些变量就确定它们的函数作用域,不使用var意味着声明一个全局变量。

让我们来看看使用变量提升的情况: