JavaScript 变量作用域
一. 变量声明
变量用var关键字来声明,如下所示:
var num;
var a,b;
var name = "ting";
var i=0, j=1, k=2;
用var关键字申明的变量是永久的,用delete运算符删除不起作用。
var i = 2;
delete i;
console.log(i); // k = 3;
delete k;
console.log(k); //报错:ReferenceError: k is not defined.
JavaScript变量是松散类型的,可以用来保存任何数据类型。并且还可在修改变量的值时改变变量的类型。
var answer = 10;
answer = "The answer is: " + 10;
console.log(answer); //
console.log(typeof answer); //string
二. 变量作用域
变量的作用域是程序中定义这个变量的区域。函数内部声明的变量只在函数内部起作用。声明局部变量一定要使用var关键字声明。
在函数内部,局部变量作用域高于同名全局变量。
var i = 99;
function foo() {
var i = 100;
console.log(i); //100(使用局部变量)
}
foo();
console.log(i); //99(使用全局变量)
声明局部变量未使用var关键字,该变量会暴露在全局环境中,与现有的全局变量冲突。如下代码中,函数内部的变量a未使用var关键字,与全局环境中的a冲突,在全局环境中调用a。
var a = 5;
function foo() {
a = 10;
b = 15;
console.log(a); //
console.log(b); //
}
foo();
console.log(a); //
console.log(b); //
变量在未声明的情况下被初始化,会被添加到全局环境。
var add = function(a,b) {
var sum = a + b;
return sum;
}
var res = add(2,3);
console.log(res); //
console.log(sum); //ReferenceError: sum is not defined
var add = function(a,b) {
sum = a + b;
return sum;
}
var res = add(2,3);
console.log(sum); //
JavaScript执行代码时,会创建一个上下文执行环境,全局环境是最外围的环境。每个函数在被调用时都会创建自己的执行环境,当函数执行完,当前执行环境被销毁。
每个执行环境都有一个与之关联的作用域链。在执行代码时,JavaScript引擎会通过搜索执行环境的作用域链来解析变量和函数名这样的标识符。 解析过程从作用域链的前端开始,向上逐级查询与给定名字匹配的标识符,一旦找到标识符,搜索过程就停止,否则继续沿作用域链向上搜索,一直搜索到全局对象。如果没有搜到,则认为该标识符未定义。标识符在作用域链中的位置越深,查找和访问它的时间越长,所以尽可能使用局部变量。
全局环境只能访问在全局环境中定义的变量和函数,不能直接访问局部环境中的任何数据。
三. 没有块级作用域
JavaScript中没有块级作用域,举个例子。如果JavaScript中有块级作用域的话,控制台输出的应该是undefined。但实际上控制台输出的是100,这是为什么呢? 原因在于:没有块级作用域,变量i没有被销毁,因此还能访问到这个变量。
for(var i=0; i<100; i++) {
//todo
}
console.log(i); //
JavaScript中存在函数作用域。当foo函数执行完毕后,函数内的变量将被销毁,因此控制台报错。
function foo() {
var bar = "fn";
}
foo();
console.log(bar); //报错:ReferenceError: bar is not defined.
函数作用域模拟块级作用域。
(function() {
for(var i=0; i<100; i++) {
//todo
}
})();
console.log(i); //报错:ReferenceError: bar is not defined.
再看一例:局部变量a在整个foo函数内部都有定义的,隐藏了全局变量a。但第一个console在变量初始化之前,所以其值为undefined。
var a = 8;
var foo = function() {
console.log(a); //undefined
var a = 5;
console.log(a); //
};
foo();
四. 未赋值的变量和未定义的变量
未赋值的变量值为undefined,而使用未定义的变量会引起错误。
var a;
console.log(a); //undefined
console.log(b); //ReferenceError: b is not defined
五. 垃圾收集(garbage collection)
JavaScript具有自动垃圾收集机制,Javascript解释器可以检测到何时程序不再使用一个对象,就把它所占用的内存释放。
时间:2014-10-22
地点:合肥
引用:http://wlog.cn/javascript/javascript-variable-scope-chain.html
http://segmentfault.com/blog/liangyi/1190000000692129
JavaScript 变量作用域的更多相关文章
- 【转】javascript变量作用域、匿名函数及闭包
下面这段话为摘抄,看到网上大多数人使用的是变量在使用的时候声明而不是在顶端声明,也可能考虑到js查找变量影响性能的问题,哪里用就在哪里声明,也很好. 在Javascript中,我们在写函数的时候往往需 ...
- 第一百零六节,JavaScript变量作用域及内存
JavaScript变量作用域及内存 学习要点: 1.变量及作用域 2.内存问题 JavaScript的变量与其他语言的变量有很大区别.JavaScript变量是松散型的(不强制类型)本质,决定了它只 ...
- JavaScript变量作用域
全部变量拥有全局作用域,局部变量拥有局部作用域(这里注意函数的参数也是局部变量) 1.在函数体内,局部变量的优先级高于同名的全局变量. 我的理解就是当你同时定义了同名的局部变量和全局变量时,函数体内返 ...
- 深入理解Javascript变量作用域
在学习JavaScript的变量作用域之前,我们应当明确几点: a.JavaScript的变量作用域是基于其特有的作用域链的. b.JavaScript没有块级作用域. c.函数中声明的变量在整个函数 ...
- JavaScript 变量作用域 详解
变量作用域要点 - 在JavaScript中没有块级作用域,只有函数作用域 - 在函数体内,局部变量的优先级高于同名的全局变量 - 在全局作用域编写代码时可以不写var语句,但声明局部变量时必须使用v ...
- JavaScript变量作用域(Variable Scope)和闭包(closure)的基础知识
在这篇文章中,我会试图讲解JavaScript变量的作用域和声明提升,以及许多隐隐藏的陷阱.为了确保我们不会碰到不可预见的问题,我们必须真正理解这些概念. 基本定义 作用范围是个“木桶”,里面装着变量 ...
- 基础系列(1)之干掉JavaScript变量作用域
今天去某顺公司面试,发现一些基础知识都不记得了,于是乎决定把js基础系列的全部梳理一遍,今天就整理下js变量作用域的相关基础知识点,配合最常遇到的笔试题阐述. 题一: var g = "a ...
- 深入浅出JavaScript变量作用域
在学习JavaScript的变量作用域之前,我们应当明确几点: JavaScript的变量作用域是基于其特有的作用域链的. JavaScript没有块级作用域. 函数中声明的变量在整个函数中都有定义. ...
- JavaScript 变量作用域和声明提升
一.变量作用域 说到这个概念,不有自主的想到this,scope 这两个关键字. JavaScript的this总是指向一个明确的对象,这个对象是在执行的时候动态绑定的.通俗的说就是谁调用我,我的th ...
随机推荐
- T-SQL编程 —— 用户自定义函数(标量函数)
用户自定义函数 在使用SQL server的时候,除了其内置的函数之外,还允许用户根据需要自己定义函数.根据用户定义函数返回值的类型,可以将用户定义的函数分为三个类别: 返回值为可更新表的函数 如果用 ...
- 两行代码搞定 JavaScript 的日期验证
我们通常在 JavaScript 中验证日期,基本的思路大概是,先判断年月日是否有效,再判断当月是否有当日,比如一些月份没有 31 日,平年二月没有 29.30 日,闰年二月没有 30 日等等. 偶然 ...
- system_call中断处理过程
张雨梅 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-10000 1.给menuos添加命令 改 ...
- 利用Github Pages生成一个快速访问的网址,展示自己的项目
利用Github Pages展示自己的项目 写了个小项目,想要分享出去,一直在用Github管理项目,了解到Github还有Github Pages功能,然后惊喜的发现Github pages可以搭建 ...
- Android 四大组件之四(ContentProvider)
ContentProvider调用关系: ContentProvider(数据提供者)是应用程序之间共享数据的一种接口机制,是一种更为高级的数据共享方法. ContentProvider可以指定需要共 ...
- HTML5 十大新特性(二)——表单新特性
H5的表单新特性可以分为两大类. 一.10个input的type值 1.email:邮件输入域,在表单提交时提供简单的邮箱格式验证,并弹出一个提示窗口. 2.url:地址输入域,在表单提交时提供简单的 ...
- 记录centos6.8安装Oracle10.2.0.1过程中的错误解决
[root@hadoop01 database]# ./runInstaller ./runInstaller: /opt/database/install/.oui: /lib/ld-linux.s ...
- R语言实战(二)数据管理
本文对应<R语言实战>第4章:基本数据管理:第5章:高级数据管理 创建新变量 #建议采用transform()函数 mydata <- transform(mydata, sumx ...
- 4.AE中的缩放,书签
1.书签 private void textBox1_TextChanged(object sender, EventArgs e) { if (txtBookmark.Text == "& ...
- 十天精通CSS3学习笔记 part3
第8章 CSS3中的变形与动画(上) 变形--旋转 rotate() 旋转rotate()函数通过指定的角度参数使元素相对原点进行旋转.它主要在二维空间内进行操作,设置一个角度值,用来指定旋转的幅度. ...