最新消息:前端博客、web前端博客、Angularjs、javascript、jQuery、HTML5、CSS3

javascript变量作用域一点小总结

JavaScript AZ 983浏览 0评论

前言:javascript里变量作用域是个经常让人头痛抓狂的问题,下面通过10++个题目,对经常遇到又容易出错的情况进行了简单总结,代码样例很短很简单

 

题目一

JavaScript代码
  1. var name = ‘casper’;
  2. alert(name);  //毫无疑问地输出:casper

 

 

题目二

JavaScript代码
  1. alert(name);  //报错:对象未定义,即使用一个压根就不存在的变量,所以出错
  2. age = 24;  //这里木有错,但age不是为定义吗?翻下犀牛书,明白了
  3.            //给一个未定义的变量赋值,会创建一个全局变量,相当于:var age = 24

题目三

JavaScript代码
  1. alert(name);  //name下面才定义,这里肯定报错了吧?错!这里弹出:undefined
  2. var name = ‘casper’;

解释:javascript代码在解析的时候,都会搜索下var声明的变量,并将其声明提前,实际的过程如下:

JavaScript代码
  1. var name;  //光声明name变量,但未赋值,所以为此时为:undefined
  2. alert(name);
  3. name = ‘casper’;

 

题目四

JavaScript代码
  1. var name = ‘casper’;
  2. function show(){
  3.     alert(name);
  4.     name = ‘hello’;  //全局变量name的值改为’hello’
  5. }
  6. show();  //输出:casper

 

题目五

JavaScript代码
  1. var name = ‘casper’;
  2. function show(){
  3.     alert(name);  //输出:undefined,是不是有想死的心
  4.     var name = ‘hello’;  //注意:与题目四相比,此处name前多了个var,
  5. }
  6. show();

解释:在函数show中,name是个局部变量,题目三的原理同样适用于此,即函数show内部实际为

(小知识点补充:当函数内部存在与外部全局变量同名的局部变量,优先使用局部变量,此处为name)

JavaScript代码
  1. function show(){
  2.     var name;
  3.     alert(name);
  4.     name = ‘hello’;
  5. }

 

题目六

JavaScript代码
  1. var list = [1,2,3];
  2. function show(){
  3.     if(typeof list === ‘undefined’){
  4.         list = [];
  5.     }
  6.     alert(list.length);
  7. };
  8. show();  //结果:3,是不是一目了然= =,稍等,请接着看第七题

 

题目七

JavaScript代码
  1. var list = [1,2,3];
  2. function show(){
  3.     if(typeof list === ‘undefined’){
  4.         var list = [];  //请注意,与题目六相比,这里多了个var
  5.     }
  6.     alert(list.length);
  7. };
  8. show();  //结果:0,是不是突然有了想死的冲动

解释:javascript没有块级作用域(即由{}限定的作用域),函数中声明的所有变量,无论在哪里声明,在整个函数中都是有定义的,这点跟C++等灰常不同,赶紧扭转思想与时俱进

于是,再来看下show方法实际的内部解析逻辑

JavaScript代码
  1. function show(){
  2.     var list;  //list为局部变量,且此处尚未赋值
  3.     if(typeof list === ‘undefined’){
  4.         list = [];
  5.     }
  6.     alert(list.length);
  7. };

 

题目八

JavaScript代码
  1. alert(typeof show);  //结果:function,请相信你的眼睛,你没有看错
  2. function show(){}

解释:javascript代码解析的过程,类似 function show() 这种形式声明的函数,跟var声明的变量一样,都会被提到最前面,不同的是,函数声明跟定义同时完成,但var声明的变量的赋值在后面才会完成

 

题目九

JavaScript代码
  1. alert(typeof show);  //结果:undefined,请再次擦亮你的眼睛,你的确没有看错
  2. var show = function(){};

解释:采用函数定义式以及函数表达式定义函数,两者过程之间存在一些区别

函数定义式:function show(){}

函数表达式:var show = function(){}

采用函数定义式声明的方法,函数的定义会提前;而采用函数表达式声明的方法,函数的定义,跟采用var声明的局部变量一样,函数声明会提前,但函数定义位置不变,过程如下:

JavaScript代码
  1. var show;
  2. alert(typeof show);
  3. show = function(){};

 

题目十

JavaScript代码
  1. var data = {name:‘casper’};
  2. function data(){
  3.     alert(‘casper’);
  4. }
  5. data();  //TypeError: object is not a function

更正:在火狐浏览器中,结果是弹出 casper 的警告框!
而在chrome和IE9中,的确提示说data是一个对象,而不是一个函数

是不是有砸显示器的冲动。。。data此时其实为{name:’casper’},把一个object当函数调用,于是报错了

前面说过,函数声明(通过函数定义式)、var声明的变量会被提前,但是会有先后顺序之分,如下:

JavaScript代码
  1. function data(){
  2.     alert(‘casper’);
  3. }
  4. var data;
  5. data = {name:‘casper’};
  6. data();

 

JavaScript代码
  1. //略微修改下,结果就不同鸟:
  2. var data = {name:‘casper’};
  3. var data = function (){  //通过函数表达式声明函数
  4.     alert(‘casper’);
  5. }
  6. data();  //结果:casper
  7. //结合上文不难猜想过程如下:
  8. var data;
  9. data = {name:‘casper’};
  10. data = function (){
  11.     alert(‘casper’);
  12. }
  13. data();  //结果:casper

小结:javascript作用域的问题着实令人头疼,作为基础中的基础,把它搞清楚还是很有必要的,上面列举了不少 容易出错的场景,但实际情况可能比这还复杂,闭包、this、不同段之间的脚本(即脚本分散写在多段<script>标签中)等这里就不展开 了。以上内容如有错漏 或 讲解不当之处,欢迎指出。

转载请注明:TUTERM.COM » javascript变量作用域一点小总结

如果您觉得本文的内容对您的学习有所帮助,您可以支付宝(左)或微信(右):
alipay weichat

您必须 登录 才能发表评论!