你了解Javascript中潜藏在变量中的那些陷阱吗
不管你是刚开始学习Javascript抑或是已经使用Javascript很长一段时间了,我相信你都会碰到一些Javascript变量作用域的陷阱。可能你已经习惯了这些问题,因为在问题发生以后你可以解决他们。但是如果你能理解这些陷阱发生的机制以及它可能会在什么地方首次出现,那你就可以避免掉入这些陷阱之中。
现在Javascript已经不再是一个简单的玩具了,不仅仅用来做一些页面上的特效。能在Javascript系统中生存下来的那些人都是对Javascript的工作机制有很深入的了解的那些人。下面我们将要通过几个问题来讨论这些可能出现的陷阱,并且我们会讨论为什么出现这些陷阱以及我们应该怎么解决。
问题1
var a = 'abc';
function foo()
{
console.log(a);
var a = 'xyz';
console.log(a);
}
foo();
在上面的代码中,第一个console.log(a)的值打印出来是多少,第二个console.log(a)的值打印出来又是多少?
如果你说第一个console.log(a)打印出来是‘abc’那你就错了。我能理解为什么会出现这样的错误。我相信对于第二个console.log(a)的值我们都知道是‘xyz’。但是第二个a的值不是我们所关心的,我们关心的是第一个console.log(a)为什么不是‘abc’,那它的值究竟是什么呢?
下面我们首先来了解这样的一个知识点——无论变量在什么地方被声明,这个变量都会被提升到该变量声明的域中的顶部。这种情形就发生在上面我们写的代码中。
因此,上面代码的执行其实等价于下面的代码
var a = 'abc';
function foo()
{
var a;
console.log(a);
a = 'xyz';
console.log(a);
}
foo();
从这段代码中我们就可以看到了第一个console.log(a)的值是undefined或者是null。
对于这一点我也经常迷惑,在其他语言中如果出现这种情况——一个变量被定义了但是还没有分配值,那打印的结果应该是null,除非是我没有定义这个变量才会出现undefined。
但是在Javascript中它就是这么神奇,与其它语言的情况是不同的。在强类型的语言中,如果我们定义一个变量同时我们会指定这个变量的数据类型。因此,如果我们定义一个变量是对象类型的,那这个变量默认被分配的值是null,但是这个真正的值是0。
在Javascript中,直到变量被分配值以后我们才知道这个变量的类型。因此我们经常使用关键字var来定义变量,目的就是告诉解析器这里有一个变量,但是这个变量的类型还未确定。因此任何未被分配值的变量都是undefined而不是null。
问题2
下面我们在上述代码基础上进行一些修改,代码如下
var a = 'abc';
function foo(){
a = 'xyz';
}
foo();
console.log(a);
这段代码中打印出的a的结果是什么呢?
我希望这应该是一个很容易解决的问题。这里请大家注意,当我们调用foo()函数的时候,函数里并没有重新定义a变量,只是对a进行了赋值,也就是说当前a的值为‘xyz’。由于在代码开始我们就声明了a变量并且给其赋值‘abc’,因此foo()中的a即是开始定义的那个a。
问题3
现在让我们在对代码进行改进,如下
function foo(){
a = 'xyz';
}
foo();
console.log(a);
大家注意,在上面的代码中并没有声明变量a,我们仅仅是在foo()函数中给a赋值‘xyz’,那这种情况下a打印出的值是什么呢?
可能有的人认为改代码并不能执行,也有的人认为a的值是undefined,这两种说法都是错误的。如果有人认为代码不执行的话,可能你使用Javascript的时间并不长。既然上面两种情况都不是,那a的值可能是‘xyz’了,事实也的确是这样的。为什么是这样的呢,a又是在什么地方被定义的?既然我们没有定义a变量,那肯定是系统自动在某个地方定义的了,在foo()函数里抑或是在其他的某些地方。 答案是在其他的某些地方而不是在foo()函数里。因为Javascript的规则就是这样的,如果变量没有在它被使用的域里定义,这个变量就是一个全局变量,在浏览器中这个变量window对象的一个属性。因此a的值只能是‘xyz’。
通过以上三段代码,我想说明的是我们在用Javascript编程的时候注意的变量的问题,这也是我们经常碰到的问题。只要对变量的原理有一个比较清晰的了解,我相信在工作中我们就可以避免不必要的错误,毕竟修改错误要花费我们一定的时间,从而达到事半功倍的效果。
相关文章
Do you understand JavaScript closures?
发布时间:2025/02/21 浏览次数:108 分类:JavaScript
-
The function of a closure can be inferred from its name, suggesting that it is related to the concept of scope. A closure itself is a core concept in JavaScript, and being a core concept, it is naturally also a difficult one.
Do you know about the hidden traps in variables in JavaScript?
发布时间:2025/02/21 浏览次数:178 分类:JavaScript
-
Whether you're just starting to learn JavaScript or have been using it for a long time, I believe you'll encounter some traps related to JavaScript variable scope. The goal is to identify these traps before you fall into them, in order to av
How much do you know about the Prototype Chain?
发布时间:2025/02/21 浏览次数:150 分类:JavaScript
-
The prototype chain can be considered one of the core features of JavaScript, and certainly one of its more challenging aspects. If you've learned other object-oriented programming languages, you may find it somewhat confusing when you start
如何在 MySQL 中声明和使用变量
发布时间:2024/03/26 浏览次数:115 分类:MySQL
-
当你需要在 MySQL 中的脚本中存储单个值时,最好的方法是使用变量。变量有不同的种类,有必要知道何时以及如何使用每种类型。
如何在 JavaScript 中合并两个数组而不出现重复的情况
发布时间:2024/03/23 浏览次数:86 分类:JavaScript
-
本教程介绍了如何在 JavaScript 中合并两个数组,以及如何删除任何重复的数组。