你了解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编程的时候注意的变量的问题,这也是我们经常碰到的问题。只要对变量的原理有一个比较清晰的了解,我相信在工作中我们就可以避免不必要的错误,毕竟修改错误要花费我们一定的时间,从而达到事半功倍的效果。
相关文章
C 语言中的 extern 关键字
发布时间:2023/05/07 浏览次数:114 分类:C语言
-
本文介绍了如何在 C 语言中使用 extern 关键字。C 语言中使用 extern 关键字来声明一个在其他文件中定义的变量
比较 C 语言中的字符
发布时间:2023/05/07 浏览次数:151 分类:C语言
-
本教程介绍了如何在 C 语言中比较字符 char,char 变量是一个 8 位的整数值,从 0 到 255。这里,0 代表 C-null 字符,255 代表空符号。
使用 C 语言的 setenv 函数访问环境变量
发布时间:2023/05/07 浏览次数:52 分类:C语言
-
在 C 语言中使用 setenv 函数导出环境变量 在 Unix-base 系统上运行的每个程序都有一个环境,它收集了主要由 shell 和其他用户空间程序使用的变量值对。
使用 CSS 和 JavaScript 制作文本闪烁
发布时间:2023/04/28 浏览次数:146 分类:CSS
-
本文提供了使用 CSS、JavaScript 和 jQuery 使文本闪烁的详细说明。
MATLAB 检查变量类型
发布时间:2023/04/23 浏览次数:92 分类:MATLAB
-
在本教程中,我们将讨论如何使用 MATLAB 中的 class() 和 whos 函数检查给定变量的类型。