javascript变量作用域使用中常见错误总结


Posted in Javascript onMarch 26, 2013

今天在rainweb的博客上,看到了这篇非常好的文章,觉得非常有必要分享出来,相信大家认真读完这篇文章,对js作用域的理解又会上升到一个新的台阶。

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

题目一

var name = 'casper'; alert(name); //毫无疑问地输出:casper

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

题目三
alert(name); //name下面才定义,这里肯定报错了吧?错!这里弹出:undefined 
var name = 'casper';

解释:javascript代码在解析的时候,都会搜索下var声明的变量,并将其声明提前,实际的过程如下:
var name; //光声明name变量,但未赋值,所以为此时为:undefined 
alert(name); name = 'casper';

题目四
var name = 'casper'; 
function show(){ 
alert(name); 
name = 'hello'; //全局变量name的值改为'hello' 
} 
show(); //输出:casper

题目五
var name = 'casper'; 
function show(){ alert(name); //输出:undefined,是不是有想死的心 
var name = 'hello'; //注意:与题目四相比,此处name前多了个var, 
} show();

解释:在函数show中,name是个局部变量,题目三的原理同样适用于此,即函数show内部实际为
(小知识点补充:当函数内部存在与外部全局变量同名的局部变量,优先使用局部变量,此处为name)
function show(){ var name; alert(name); name = 'hello'; }
题目六
var list = [1,2,3]; 
function show(){ if(typeof list === 'undefined') 
{ list = []; } 
alert(list.length); 
}; 
show(); //结果:3,是不是一目了然= =,稍等,请接着看第七题

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

解释:javascript没有块级作用域(即由{}限定的作用域),函数中声明的所有变量,无论在哪里声明,在整个函数中都是有定义的,这点跟C++等灰常不同,赶紧扭转思想与时俱进
于是,再来看下show方法实际的内部解析逻辑
function show(){ var list; //list为局部变量,且此处尚未赋值 
if(typeof list === 'undefined'){ 
list = []; } 
alert(list.length); };

题目八
alert(typeof show); //结果:function,请相信你的眼睛,你没有看错 
function show(){}

解释:javascript代码解析的过程,类似 function show() 这种形式声明的函数,跟var声明的变量一样,都会被提到最前面,不同的是,函数声明跟定义同时完成,但var声明的变量的赋值在后面才会完成
题目九
alert(typeof show); //结果:undefined,请再次擦亮你的眼睛,你的确没有看错 
var show = function(){};

解释:采用函数定义式以及函数表达式定义函数,两者过程之间存在一些区别
函数定义式:function show(){}
函数表达式:var show = function(){}
采用函数定义式声明的方法,函数的定义会提前;而采用函数表达式声明的方法,函数的定义,跟采用var声明的局部变量一样,函数声明会提前,但函数定义位置不变,过程如下:
var show; alert(typeof show); 
show = function(){};

题目十
var data = {name:'casper'}; 
function data(){ alert('casper'); } 
data(); //TypeError: object is not a function

是不是有砸显示器的冲动。。。data此时其实为{name:'casper'},把一个object当函数调用,于是报错了
前面说过,函数声明(通过函数定义式)、var声明的变量会被提前,但是会有先后顺序之分,如下:
function data(){ alert('casper'); 
} var data; data = {name:'casper'}; 
data();

略微修改下,结果就不同鸟:
var data = {name:'casper'}; 
var data = function (){ //通过函数表达式声明函数 
alert('casper'); } 
data(); //结果:casper

结合上文不难猜想过程如下:
var data; data = {name:'casper'}; 
data = function (){ alert('casper'); } 
data(); //结果:casper
Javascript 相关文章推荐
让JavaScript拥有类似Lambda表达式编程能力的方法
Sep 12 Javascript
JS分割字符串并放入数组的函数
Jul 04 Javascript
js中点击空白区域时文本框与隐藏层的显示与影藏问题
Aug 26 Javascript
移动设备web开发首选框架:zeptojs介绍
Jan 29 Javascript
jQuery对象与DOM对象之间的相互转换
Mar 03 Javascript
js实现获取当前时间是本月第几周的方法
Aug 11 Javascript
js制作网站首页图片轮播特效代码
Aug 30 Javascript
Vue父组件调用子组件事件方法
Feb 23 Javascript
React中嵌套组件与被嵌套组件的通信过程
Jul 11 Javascript
JavaScript中call和apply方法的区别实例分析
Aug 03 Javascript
详解element-ui日期时间选择器的日期格式化问题
Apr 08 Javascript
vue监听浏览器原生返回按钮,进行路由转跳操作
Sep 09 Javascript
定时器(setTimeout/setInterval)调用带参函数失效解决方法
Mar 26 #Javascript
设为首页加入收藏兼容360/火狐/谷歌/IE等主流浏览器的代码
Mar 26 #Javascript
jquery 无限级联菜单案例分享
Mar 26 #Javascript
JSON辅助格式化处理方法
Mar 26 #Javascript
html+css+js实现xp window界面及有关功能
Mar 26 #Javascript
jquery图片放大镜功能的实例代码
Mar 26 #Javascript
EditPlus注册码生成器(js代码实现)
Mar 25 #Javascript
You might like
PHP服务器页面间跳转实现方法
2012/08/02 PHP
php读取mysql中文数据出现乱码的解决方法
2013/08/16 PHP
Linux中用PHP判断程序运行状态的2个方法
2014/05/04 PHP
PHP的Yii框架使用中的一些错误解决方法与建议
2015/08/21 PHP
Yii2 如何在modules中添加验证码的方法
2017/06/19 PHP
Package.js  现代化的JavaScript项目make工具
2012/05/23 Javascript
jquery的ajax和getJson跨域获取json数据的实现方法
2014/02/04 Javascript
js 显示base64编码的二进制流网页图片
2014/04/04 Javascript
jQuery淡入淡出元素让其效果更为生动
2014/09/01 Javascript
javascript面向对象之定义成员方法实例分析
2015/01/13 Javascript
jquery+CSS实现的水平布局多级网页菜单效果
2015/08/24 Javascript
javascript弹性运动效果简单实现方法
2016/01/08 Javascript
通过Ajax使用FormData对象无刷新上传文件方法
2016/12/08 Javascript
jQuery实现动态文字搜索功能
2017/01/05 Javascript
bootstrapvalidator之API学习教程
2017/06/29 Javascript
前端常见跨域解决方案(全)
2017/09/19 Javascript
vue实现长图垂直居上 vue实现短图垂直居中
2017/10/18 Javascript
详解ES6中的代理模式——Proxy
2018/01/08 Javascript
Vue数字输入框组件示例代码详解
2020/01/15 Javascript
OpenLayers3实现鼠标移动显示坐标
2020/09/25 Javascript
itchat接口使用示例
2017/10/23 Python
Python3之读取连接过的网络并定位的方法
2018/04/22 Python
python将txt文件读入为np.array的方法
2018/10/30 Python
Python图像处理之直线和曲线的拟合与绘制【curve_fit()应用】
2018/12/26 Python
Python mutiprocessing多线程池pool操作示例
2019/01/30 Python
Python3.5以上版本lxml导入etree报错的解决方案
2019/06/26 Python
解决Python安装cryptography报错问题
2020/09/03 Python
中国领先的汽车保养服务平台:途虎养车
2019/10/18 全球购物
北京麒麟网信息技术有限公司网络游戏测试面试题
2013/09/28 面试题
研究生自荐信
2013/10/09 职场文书
应届护士推荐信
2013/11/16 职场文书
会计工作心得体会
2014/01/13 职场文书
论群众路线学习心得体会
2014/10/31 职场文书
感恩父母主题班会
2015/08/12 职场文书
jQuery class属性操作addClass()与removeClass()、hasClass()、toggleClass()
2021/03/31 jQuery
《宝可梦》动画制作25周年到来 官方发布特别纪念视频
2022/04/01 日漫