javasript 变量作用域 (一)
现在Web前端开发首选语言是javascript,很多开发人员写了很多javascript代码,而且网站也运行的很好。就个人经验而言我们需要弄清楚几个概念:
一 javascript执行上下文环境
写一个很简单的hello world从页面弹出,代码如下
function foo() { var hText = "hello world!"; alert(hText); } foo();
通过script标签将上面的代码嵌入到页面,刷新页面马上就能看到弹出"hello world!"
如果我们将foo()替换为window.foo()也能正常运行。我们可简单的认为foo函数的执行上下文环境是window。
二 没有块级作用域
观察如下代码
for(i=0; i<=10; ++i) { //some codes } alert(i);
也许很多人说会弹出undefined,
也有人说会弹出11,那么恭喜你答对了。如果是因为你对var了解多,认为我们声明了一个全局变量,故而弹出11,那么恭喜你好运,是猜对的。
我们将代码换成
function foo() { for(var i=0; i<=10; i++) { // } alert(i); }
调用foo(); 有函数,var , for这下应该是undefined了, 其实这个时候还是弹出11。
我们再将alert挪个位置
function foo() { alert(i); for(var i=0; i<=10; ==i){} }
这个时候我们终于见到是undefined了,因为调用i的时候还未定义出来。在函数内部,变量还是按顺序定义执行,但是没有块级作用域,变量在整个函数范围内都可以用。
三 javascript语句
这个说起来有点绕口,我们写javascript的时候按道理说所有的代码都应该是语句。其实这个是相对函数来说,
在javascript run-time,语句会立即触发,函数只会编译不会立即执行。当javascript编译环境遇到一个函数定义时,只会解析并存储函数主体语句,等到使用()会事件触发时再执行。
alert("hello world!"); function foo(){alert("another hello world!")}
我们会马上见到hello world, 直到使用()调用foo时我们才能见到"another hello world!"。alert是一个语句,当页面加载,js run time时,立马触发。foo是函数定义不立即出发。
四 闭包
写过后台代码的童鞋都知道在一个函数里面是不能嵌套另一个函数的。但据说javascript是第一个函数式编程语言(LISP,听说而已,站的高度不够还没研究),所以能够在函数里面定义另外一个函数。而在函数里面的变量在整个函数访问都是可访问的,我们看如下的代码。
function foop() { var i=0; function fooc() { alert(i); } fooc(); }
当我们调用foop的时候,可以见到弹出0,按我个人理解,这个时候并没有任何闭包产生,因为fooc执行完的时候,变量i已经销毁。改变代码以后
function foop() { var i = 0; return function(){alert(i);} } var a = foop(); a();
这个时候一个闭包就产生了,当我们执行完var a = foop(); 按道理说foop已经执行,其内部变量应该已经销毁。但是当我们调用a()时,还是能访问到foop内部变量i的。