javascript变量作用域使用中常见错误总结
2023-06-13 09:14:48 时间
今天在rainweb的博客上,看到了这篇非常好的文章,觉得非常有必要分享出来,相信大家认真读完这篇文章,对js作用域的理解又会上升到一个新的台阶。
前言:javascript里变量作用域是个经常让人头痛抓狂的问题,下面通过10++个题目,对经常遇到又容易出错的情况进行了简单总结,代码样例很短很简单
题目一
varname="casper";alert(name);//毫无疑问地输出:casper
题目二
alert(name);//报错:对象未定义,即使用一个压根就不存在的变量,所以出错
age=24;//这里木有错,但age不是为定义吗?翻下犀牛书,明白了//给一个未定义的变量赋值,会创建一个全局变量,相当于:varage=24
题目三
alert(name);//name下面才定义,这里肯定报错了吧?错!这里弹出:undefined
varname="casper";
解释:javascript代码在解析的时候,都会搜索下var声明的变量,并将其声明提前,实际的过程如下:
varname;//光声明name变量,但未赋值,所以为此时为:undefined
alert(name);name="casper";
题目四
varname="casper";
functionshow(){
alert(name);
name="hello";//全局变量name的值改为"hello"
}
show();//输出:casper
题目五
varname="casper";
functionshow(){alert(name);//输出:undefined,是不是有想死的心
varname="hello";//注意:与题目四相比,此处name前多了个var,
}show();
解释:在函数show中,name是个局部变量,题目三的原理同样适用于此,即函数show内部实际为
(小知识点补充:当函数内部存在与外部全局变量同名的局部变量,优先使用局部变量,此处为name)
functionshow(){varname;alert(name);name="hello";}
题目六
varlist=[1,2,3];
functionshow(){if(typeoflist==="undefined")
{list=[];}
alert(list.length);
};
show();//结果:3,是不是一目了然==,稍等,请接着看第七题
题目七
varlist=[1,2,3];
functionshow(){
if(typeoflist==="undefined")
{varlist=[];//请注意,与题目六相比,这里多了个var
}alert(list.length);};
show();//结果:0,是不是突然有了想死的冲动
解释:javascript没有块级作用域(即由{}限定的作用域),函数中声明的所有变量,无论在哪里声明,在整个函数中都是有定义的,这点跟C++等灰常不同,赶紧扭转思想与时俱进
于是,再来看下show方法实际的内部解析逻辑
functionshow(){varlist;//list为局部变量,且此处尚未赋值
if(typeoflist==="undefined"){
list=[];}
alert(list.length);};
题目八
alert(typeofshow);//结果:function,请相信你的眼睛,你没有看错
functionshow(){}
解释:javascript代码解析的过程,类似functionshow()这种形式声明的函数,跟var声明的变量一样,都会被提到最前面,不同的是,函数声明跟定义同时完成,但var声明的变量的赋值在后面才会完成
题目九
alert(typeofshow);//结果:undefined,请再次擦亮你的眼睛,你的确没有看错
varshow=function(){};
解释:采用函数定义式以及函数表达式定义函数,两者过程之间存在一些区别
函数定义式:functionshow(){}
函数表达式:varshow=function(){}
采用函数定义式声明的方法,函数的定义会提前;而采用函数表达式声明的方法,函数的定义,跟采用var声明的局部变量一样,函数声明会提前,但函数定义位置不变,过程如下:
varshow;alert(typeofshow);
show=function(){};
题目十
vardata={name:"casper"};
functiondata(){alert("casper");}
data();//TypeError:objectisnotafunction
是不是有砸显示器的冲动。。。data此时其实为{name:"casper"},把一个object当函数调用,于是报错了
前面说过,函数声明(通过函数定义式)、var声明的变量会被提前,但是会有先后顺序之分,如下:
functiondata(){alert("casper");
}vardata;data={name:"casper"};
data();
略微修改下,结果就不同鸟:
vardata={name:"casper"};
vardata=function(){//通过函数表达式声明函数
alert("casper");}
data();//结果:casper
结合上文不难猜想过程如下:
vardata;data={name:"casper"};
data=function(){alert("casper");}
data();//结果:casper
相关文章
- javascript 高级教程 视频_精通JavaScript
- JavaScript[容易忽视的错误]:当续行遇到换行,换行符丢失
- 【说站】JavaScript闭包如何创建
- 【说站】JavaScript选择排序的实现
- 用javascript分类刷leetcode23.并查集(图文视频讲解)
- JavaScript 日期格式化详解编程语言
- JavaScript学习总结(九)——Javascript面向(基于)对象编程详解编程语言
- 从JavaScript的函数重名看其初始化方式
- 错误剖析之JavaScript的9个陷阱及评点
- Javascript常用运算符(Operators)-javascript基础教程
- Javascript更新JavaScript数组的uniq方法
- javascript尚未实现错误解决办法
- JavaScript基础问答二
- javascript入门基础之私有变量
- IE6下出现JavaScript未结束的字符串常量错误的解决方法
- javascript中的绑定与解绑函数应用示例
- Javascript解析URL方法详解
- Javascript学习笔记之对象篇(一):对象的使用和属性
- JavaScript中伪协议javascript:使用探讨
- Javascript的setTimeout()使用闭包特性时需要注意的问题