话不多说,我们先看代码:
function f (){ fff = 999; } f(); console.log(fff);
我们定义了一个名为 f 的函数,函数内没有对变量进行声明,直接给 fff 变量进行了赋值,并且在外部调用了 f 函数,我们输出一下 fff 的变量,大家猜一下代码效果如何:
它可以正常输出。。。
我们再看另一段代码:
function f (){ var fff = 999; } f(); console.log(fff);
这段代码不同的地方是,在函数体内我们按规定对变量进行了声明。那么这段代码的效果是:
fff is not defined
奇了怪了是吧,我规规矩矩的声明变量倒不行,不声明直接赋值,竟然可以在函数外使用函数内的变量,这似乎不符合我们的认知,那么问题出在了哪里?
首先我们知道JavaScript中有一个内置对象是window,所有在脚本中(没有在函数的范围内)通过var定义的变量,都挂在window对象上,在任意位置,一个变量的赋值都可以看做是在window上寻找这个变量。
我们实测一下:
var aaa = 777; console.log(window)
果不其然,我们在window对象中找到了这个变量。
function f (){ fff = 999; }
这段代码在解析的时候,它会把 fff = 999,当做是window.fff = 999。
所以这个函数通过外部调用之后,可以在函数外使用函数内的变量,因为这个变量已经挂在了window对象上。
function f (){ fff = 999; } f(); console.log(window)
function f (){ window.fff = 999; } f(); console.log(window)
经过我们的测试,实际效果和预期一样。
这个问题之前当过面试题,这是一种很危险的做法,很容易导致程序出现问题,所以我们在定义变量时一定不要忘记写var,尤其是函数内,不然会制造出一些意想不到的bug。我们要尽量避免这种情况的发生,并且如何面试时被问到,要知道这个问题是什么情况。