javascript中的变量作用域以及变量提升
2013-10-23 23:29
686 查看
在javascript中,理解变量的作用域以及变量提升是非常有必要的。这个看起来是否很简单,但其实并不是你想的那样,还要一些重要的细节你需要理解。
变量作用域分为局部作用域和全局作用域。
函数级别作用域的一个例子:
[code]
[/code]
没有块级作用域:
[code]//theblocksinthisifstatementdonotcreatealocalcontextforthenamevariable
[/code]
不要忘记使用var关键字
如果声明一个变量的时候没有使用var关键字,那么这个变量将是一个全局变量!
[code]varname="MichaelJackson";
如果在全局作用域中什么的变量在局部作用域中再次声明,那么在局部作用域中调用这个变量时,优先调用局部作用域中声明的变量:
[/code]
每一个在函数外部声明或者定义的变量都是一个全局对象,所以这个变量可以在任何地方被使用,例如:
[code]varmyName="zhou";
[/code]
如果一个变量第一次初始化/声明的时候没有使用var关键字,那么他自动加入到全局作用域中。
[code]//age初始化时没有使用var关键字,所以它是一个全局变量
[/code]
setTimeout中的函数是在全局作用域中执行的
setTimeout中的函数所处在于全局作用域中,所以函数中使用this关键字时,这个this关键字指向的是全局对象(Window):
[code]varValue2=20;
[/code]
但是,如果这个变量或者函数其中是赋值了的,那么另外一个将无法覆盖它:
[code]varmyName="Richard";//Thisisthevariableassignment(initialization)thatoverridesthefunctiondeclaration.
[/code]
最后一点,在严格模式下,如果没有先声明变量就给变量赋值将会报错!
变量作用域
“一个变量的作用域表示这个变量存在的上下文。它指定了你可以访问哪些变量以及你是否有权限访问某个变量。”变量作用域分为局部作用域和全局作用域。
局部变量(处于函数级别的作用域)
不像其他对面对象的编程语言(比方说C++,Java等等),javascript没有块级作用域(被花括号包围的);当是,javascript有拥有函数级别的作用域,也就是说,在一个函数内定义的变量只能在函数内部访问或者这个函数内部的函数访问(闭包除外,这个我们过几天再写个专题)。函数级别作用域的一个例子:
varname="Richard";
[code]
functionshowName(){
varname="Jack";//localvariable;onlyaccessibleinthisshowNamefunction
console.log(name);//Jack
}
console.log(name);//Richard:theglobalvariable
[/code]
没有块级作用域:
varname="Richard";
[code]//theblocksinthisifstatementdonotcreatealocalcontextforthenamevariable
if(name){
name="Jack";//thisnameistheglobalnamevariableanditisbeingchangedto"Jack"here
console.log(name);//Jack:stilltheglobalvariable
}
//Here,thenamevariableisthesameglobalnamevariable,butitwaschangedintheifstatement
console.log(name);//Jack
[/code]
//Ifyoudon'tdeclareyourlocalvariableswiththevarkeyword,theyarepartoftheglobalscope
[code]varname="MichaelJackson";
functionshowCelebrityName(){
console.log(name);
}
functionshowOrdinaryPersonName(){
name="JohnnyEvers";
console.log(name);
}
showCelebrityName();//MichaelJackson
//nameisnotalocalvariable,itsimplychangestheglobalnamevariable
showOrdinaryPersonName();//JohnnyEvers
//TheglobalvariableisnowJohnnyEvers,notthecelebritynameanymore
showCelebrityName();//JohnnyEvers
//Thesolutionistodeclareyourlocalvariablewiththevarkeyword
functionshowOrdinaryPersonName(){
varname="JohnnyEvers";//Nownameisalwaysalocalvariableanditwillnotoverwritetheglobalvariable
console.log(name);
}
局部变量优先级大于全局变量
如果在全局作用域中什么的变量在局部作用域中再次声明,那么在局部作用域中调用这个变量时,优先调用局部作用域中声明的变量:
varname="Paul";
functionusers(){
//Here,thenamevariableislocalandittakesprecedenceoverthesamenamevariableintheglobalscope
varname="Jack";
//Thesearchfornamestartsrighthereinsidethefunctionbeforeitattemptstolookoutsidethefunctionintheglobalscope
console.log(name);
}
users();//Jack
[/code]
全局变量
所有在函数外面声明的变量都处于全局作用域中。在浏览器环境中,这个全局作用域就是我们的Window对象(或者整个HTML文档)。每一个在函数外部声明或者定义的变量都是一个全局对象,所以这个变量可以在任何地方被使用,例如:
//nameandsexisnotinanyfunction
[code]varmyName="zhou";
varsex="male";
//他们都处在window对象中
console.log(window.myName);//paul
console.log('sex'inwindow);//true
[/code]
如果一个变量第一次初始化/声明的时候没有使用var关键字,那么他自动加入到全局作用域中。
functionshowAge(){
[code]//age初始化时没有使用var关键字,所以它是一个全局变量
age=20;
console.log(age);
}
showAge();//20
console.log(age);//因为age是全局变量,所以这里输出的也是20
[/code]
setTimeout中的函数是在全局作用域中执行的
setTimeout中的函数所处在于全局作用域中,所以函数中使用this关键字时,这个this关键字指向的是全局对象(Window):
varValue1=200;
[code]varValue2=20;
varmyObj={
Value1:10,
Value2:1,
caleculatedIt:function(){
setTimeout(function(){
console.log(this.Value1*this.Value2);
},1000);
}
}
myObj.caleculatedIt();//4000
为了避免对全局作用域的污染,所以一般情况下我们尽可能少的声明全局变量。
变量提升(VariableHoisting)
所以的变量声明都会提升到函数的开头(如果这个变量在这个函数里面)或者全局作用域的开头(如果这个变量是一个全局变量)。我们来看一个例子:functionshowName(){
console.log("FirstName:"+name);
varname="Ford";
console.log("LastName:"+name);
[/code]
}
showName();
//FirstName:undefined
//LastName:Ford
//Thereasonundefinedprintsfirstisbecausethelocalvariablenamewashoistedtothetopofthefunction
//Whichmeansitisthislocalvariablethatgetcallsthefirsttime.
//ThisishowthecodeisactuallyprocessedbytheJavaScriptengine:
functionshowName(){
varname;//nameishoisted(notethatisundefinedatthispoint,sincetheassignmenthappensbelow)
console.log("FirstName:"+name);//FirstName:undefined
name="Ford";//nameisassignedavalue
//nownameisFord
console.log("LastName:"+name);//LastName:Ford
}
函数声明会覆盖变量声明
如果存在函数声明和变量声明(注意:仅仅是声明,还没有被赋值),而且变量名跟函数名是相同的,那么,它们都会被提示到外部作用域的开头,但是,函数的优先级更高,所以变量的值会被函数覆盖掉。//BoththevariableandthefunctionarenamedmyName
varmyName;
functionmyName(){
console.log("Rich");
}
//Thefunctiondeclarationoverridesthevariablename
console.log(typeofmyName);//function
但是,如果这个变量或者函数其中是赋值了的,那么另外一个将无法覆盖它:
//Butinthisexample,thevariableassignmentoverridesthefunctiondeclaration
[code]varmyName="Richard";//Thisisthevariableassignment(initialization)thatoverridesthefunctiondeclaration.
functionmyName(){
console.log("Rich");
}
console.log(typeofmyName);//string
[/code]
相关文章推荐
- 一个典型的例子理解JavaScript作用域以及变量提升
- javascript中的变量作用域以及变量提升详细介绍
- javascript中的变量作用域以及变量提升详细介绍
- javascript中的变量作用域以及变量提升详细介绍
- javascript中的变量作用域以及变量提升详细介绍
- 【JavaScript】变量提升以及var对变量提升的
- Javascript作用域和变量提升
- Javascript作用域和变量提升
- JavaScript的作用域和变量提升
- 【JavaScript】变量提升以及var对变量提升的
- JavaScript中作用域和作用域链的简单理解(变量提升)
- 深入理解Javascript作用域与变量提升
- Javascript作用域和变量提升
- JavaScript学习(四):JavaScript类型转换以及变量作用域
- Javascript作用域和变量提升
- 关于对javascript的局部变量以及全局变量作用域的追踪
- JavaScript 中的执行环境、作用域(scope)以及变量提升(hoisting)
- JavaScript的变量及函数(变量提升、嵌套作用域、条件语句、严格模式、IIFE、闭包、模块化、this、原型)
- javascript的变量提升和作用域
- JavaScript中的作用域与函数和变量声明的提升