JavaScript函数变量作用域
变量作用域
在JavaScript中,用var申明的变量实际上是有作用域的。
如果一个变量在函数体内部申明,则该变量的作用域为整个函数体,在函数体外不可引用该变量。
如果两个不同的函数各自申明了同一变量,那么该变量只在各自的函数体内起作用。换句话说,不同函数内部的同名变量互相独立,互不影响。
由于JavaScript的函数可以嵌套,此时,内部函数可以访问外部函数定义的变量,反过来则不行:
function foo() {
var x = 1;
function bar() {
var y = x + 1 ;//bar可以访问foo的变量x
}
var z = y + 1;//ReferenceError!foo不可以访问bar的变量y!
}
如果内部函数和外部函数的变量名重名怎么办?
function foo() {
var x = 1;
function bar() {
var x = 'A';
alert('x in bar() =' + x);//'A'
}
alert('x in foo() =' + x );//
bar();
}
JavaScript的函数在查找变量时从自身函数定义开始,从“内”向“外”查找。如果内部函数定义了与外部函数重名的变量,则内部函数的变量将“屏蔽”外部函数的变量。
变量提升
JavaScript的函数定义有个特点,它会先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部:
function foo() {
var x = "Hello," + y ;
alert(x);
var y = "Bob";
}
foo();//Hello,undefined
语句 var x = "Hello," + y ;并不会报错,原因是变量y在稍后申明了。但是alert显示的是Hello,undefined,说明变量y的值是undefined,这正是因为JavaScript引擎自动提升了变量y的声明,但是不会提升变量y的赋值语句。
对于上述的foo()函数,JavaScript引擎看到的代码相当于:
function foo() {
var y;//提升变量y的申明
var x = 'Hello,' + y ;
alert(x);
y='Bob';
}
tips:所以在JavaScript函数内部要首先申明所有变量。最常见的做法是用一个var申明函数内部用到的所有变量:
function foo() {
var
x=1,//x初始化为1
y=x+1,//y初始化为2
z,i;//z和i为undefined
//其他语句
for(i = 0; i<100; i++){
...
}
}
全局作用域
不在任何函数内定义的变量就具有全局作用域。JavaScript默认有一个全局对象window,全局作用域的变量实际上被绑定到window的一个属性:
var course = 'Learn JavaScript';
alert(course);//'Learn JavaScript'
alert(window.course);//'Learn JavaScript'
因此,直接访问全局变量course和访问window.course是完全一样的。
由于函数定义有两种方式,以变量方式var foo = function () {}定义的函数实际上也是一个全局变量。因此,顶层函数的定义也被视为一个全局变量
名字空间
全局变量会绑定到window上,不同的JavaScript文件如果使用了相同的全局变量,或者定义了相同名字的顶层函数,都会造成命名冲突,并且很难被发现。
减少冲突的一个方法是把自己的所有变量和函数全部绑定到一个全局变量中。
//唯一的全局变量MYAPP:
var MYAPP = {};
//其他变量:
MYAPP.name = 'myapp';
MYAPP.version = 1.0;
//其他函数
MYAPP.foo = function () {
return 'foo';
};
把自己的代码全部放入唯一的命名空间MYAPP中,会大大减少全局变量冲突的可能。
局部作用域
由于JavaScript的变量作用域实际上是函数内部,我们在for循环等语句块中无法定义具有局部作用域的变量:
'use strict':
function foo() {
for( var i = 0 ; i < 100; i++){
//
}
i +=100;//仍然可以引用变量i
}
为了解决块级作用域,ES6引入了新的关键字let,用let替代var可以申明一个块级作用域的变量:
'use strict':
function foo() {
var sum = 0 ;
for (let i = 0 ; i < 100 ; i++){
sum +=i;
}
i += 1;//SyntaxError
}
常量:
由于var和let申明的是变量,在ES6之前是不行的,我们通常用全部大写的变量来表示“这是一个常量,不要修改它的值”:
var PI = 3.14;
ES6标准引入了新的关键字const来定义常量,const与let都具有块级作用域:
'use strict':
const PI = 3.14;
PI = 3;//某些浏览器不报错,但是无效果!
PI;//3.14
JavaScript函数变量作用域的更多相关文章
- [转]深入理解JavaScript的变量作用域
1.JavaScript的作用域链 2.函数体内部,局部变量的优先级比同名的全局变量高. 3.JavaScript没有块级作用域. 4.函数中声明的变量在整个函数中都有定义. 5.未使用var关键字定 ...
- 深入理解JavaScript的变量作用域(转载Rain Man之作)
在学习JavaScript的变量作用域之前,我们应当明确几点: JavaScript的变量作用域是基于其特有的作用域链的. JavaScript没有块级作用域. 函数中声明的变量在整个函数中都有定义. ...
- 深入理解JavaScript的变量作用域
在学习JavaScript的变量作用域之前,我们应当明确几点: JavaScript的变量作用域是基于其特有的作用域链的. JavaScript没有块级作用域. 函数中声明的变量在整个函数中都有定义. ...
- 函数变量作用域(python)
收集参数:该参数个数不确定 >>> def test(*params): print('参数的长度是:', len(params)); print('第二个参数是:', params ...
- Javascript之变量作用域
分析: 无论是强类型语言c#.c++.java等语言,还是弱类型语言如Javascript,所有变量可以抽象为两种类型,即局部变量和全局变量. 全局变量:整个作用域可见. 局部变量:局部可见,退出作用 ...
- javascript的变量作用域--对比js、php和c的for循环
为什么要写这篇文章呢?主要是给自己提个醒,js的水很深,需要小心点儿才能趟过去,更何况自己不是专业人士,那就得更加小心了. 看下面的js代码: <!DOCTYPE html> <ht ...
- [译]JavaScript:函数的作用域链
原文:http://blogs.msdn.com/b/jscript/archive/2007/07/26/scope-chain-of-jscript-functions.aspx 在JavaScr ...
- javascript 函数和作用域(函数,this)(六)
重点. 一.函数 1.函数介绍 函数是一块JavaScript代码,被定义一次,但可执行和调用多次.JS中的函数也是对象,所以JS函数可以像其他对象那样操作和传递,所以我们也常叫JS中的函数为函数对象 ...
- javascript 函数和作用域(闭包、作用域)(七)
一.闭包 JavaScript中允许嵌套函数,允许函数用作数据(可以把函数赋值给变量,存储在对象属性中,存储在数组元素中),并且使用词法作用域,这些因素相互交互,创造了惊人的,强大的闭包效果.[upd ...
随机推荐
- pat09-散列1. Hashing (25)
09-散列1. Hashing (25) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue The task of ...
- java使用netty的模型总结
一 由于本人的码云太多太乱了,于是决定一个一个的整合到一个springboot项目里面. 附上自己的github项目地址 https://github.com/247292980/spring-boo ...
- PowerDesigner从SqlServer数据库导入数据模型
Powerdesigner 从数据库导入数据 第一步, 打开 powerdesigner, 在菜单选择 [File] 选项, 然后在弹出的下拉单中选择 [Reverse Engineer]选项,再选择 ...
- Sturct类型装箱时会遇到的问题
Object在拆箱时会在栈空间生成一个临时变量.所以Struct在使用时尽量将内容都声明为readonly为好 [<Struct>] type Point= val mutable X:d ...
- 【转载】BootStrap表格组件bootstrap table详解
(转载,来源“脚本之家”,作者不详) 一.Bootstrap Table的引入 关于Bootstrap Table的引入,一般来说还是两种方法: 1.直接下载源码,添加到项目里面来.由于Bootstr ...
- 重构指南 - 尽快返回(Return ASAP )
尽快返回就是如果方法中的条件判断可以得到结果,则尽快返回该结果. 1. 检查条件,如果不满足就立即返回,不执行下面的逻辑. 2. 当包含大量的if else嵌套,代码可读性变差,也容易出现异常. 3. ...
- scss-算术运算符
由于scss具有编程语言的特点,那么运算符是必不可少的. 下面就通过代码实例分别做一下介绍. 一.赋值运算符: 赋值运算符就是我们最为熟悉的冒号(:),用来给声明的变量赋值. 代码实例如下: $hig ...
- sublime text 3 添加代码片段
工具>插件开发>新建代码片段 <snippet> <content> <![CDATA[ Hello, ${1:this} is a ${2:snippet} ...
- SpagoBI 和 开源ERP(iDempiere)整合入门
Created by 蓝色布鲁斯,QQ32876341,blog http://www.cnblogs.com/zzyan/ iDempiere官方中文wiki主页 http://wiki.idemp ...
- 使用CKRule实现促销管理系统
1, 常见的促销模型 促销管理系统在很多地方都有使用,大家去超市就经常体现到,感受到,不少中小型单位都其促销活动,要搞促销活动最好是有应用软件支持,这样就比较灵活管理也方便.而依靠手工处理的话效率会比 ...