未定义的变量
未声明的变量
未赋值的变量
未定义的变量 = 未声明的变量
-
尝试读取未声明的变量会引起运行时错误。
-
尝试给未声明的变量赋值不会引起错误,相反,程序会在全局作用域中隐式地声明它。
-
尝试读取未赋值的变量,将会得到一个默认值,即undefined。
变量作用域的基本规:
-
在域中以var声明的变量只在当前域或者当前域的子域起作用。
-
对变量的查找总是从当前域开始,递归向上查找各级嵌套父域,最后到达全局。因此如果给一个当前域的局部变量与父域中的局部变量或者全局变量起相同的的名字,就能有效地隐藏上级变量或全局变量。
-
javascript除函数外的任何程序段落都不是独立的域。换句话说javascript没有块级作用域
for(var i = 10;i < 10;i++)
{
do something
}
alert(i);// i = 9
javascript变量作用域是在定义时决定而不是执行时决定,也就是说词法作用域取决于源码,编译器通过静态分析就能确定,因此词法作用域也叫静态作用域。
javascript在执行每个函数实例时,都会创建一个执行环境,执行环境里包括一个调用对象,调用对象是一个scriptObject,用于保存内部变量表,内嵌函数表,父级引用表等语法分析结构
(注意内部变量表和内嵌函数表等信息是在语法分析阶段就已经得到,并保存在语法树中。函数实例执行时,会将这些信息从语法树复制到scriptObject上)。
var arg = 1;
function funcTest() {
alert(arg);
var arg = 2;
}
arg = 10;
funcTest();
该函数的输出是undefined而不是10,因为在funcTest函数执行时,进入funcTest对应的作用域,在执行到alert时遇到了变量名arg,则会在当前作用域中查找,由于arg = 2被定义在alert方法,所以在开始编译的时候,(词法分析已经获得定义的变量和方法,这也正说明了:变量作用域是在定义时决定而不是执行时决定,也就是说词法作用域取决于源码,编译器通过静态分析就能确定
)这当前作用域中存在变量arg,但并没有赋值,故arg的值为undefined。
说的很好的一篇关于作用域的文章
另一篇文章里对作用域的说明:
JavaScript中的函数是基于静态作用域(也叫词法lexical作用域),而不是动态作用域。这句话的意思是JavaScript中的函数运行在它们被定义的作用域里
,而不是它们被执行的作用域里
。在一个静态作用域里,变量永远指向它的最顶层作用域
。这是程序文本(program text)的一个属性并且与运行时调用的堆栈无关。因为匹配变量的作用域仅仅只需要分析程序文本即可,这样的作用域我们叫作静态作用域(lexical scoping)
function f1() {
var a = 20;
return function () { alert(a); }
}
var b = f1();
b();
结果:20
function f1() {
var a = 20;
return f2
}
function f2() {
alert(a);
}
var b = f1();
b();
结果:undefined (
其实是报错的,因为引用了未定义的变量)
在程序1里一个匿名函数b()
被声明时,变量a
已经被保存在作用域里。所以得到20.但是在程序2里在函数f2()
里,没有声明变量a
所以没有任何值。
一但函数被定义,它会“记住”它的作用域与作用域链。这也并不是意味着函数里的所有变量都是这样。正好相反,你可以任意的添加、修改和删除。函数里都会保存最新的变量。但是必须知道变量是什么时候被定义而并不是这个作用域里它什么时候包含的。
静态作用域的几个特点
-
在程序里特殊地方定义的变量永远指向具有相同定义的变量,即程序每次执行时被执行函数所在的作用域里相同定义的变量 (这句话没咋明白)
-
变量是可以通过静态检查(static examination)源码中的作用域里出现的标识符(var)来将其值(value)改变的,而不是把整个函数做为一个整体来执行。
分享到:
相关推荐
在《JavaScript权威指南》第五版中,对变量作用域进行了深入的介绍,通过对作者的学习笔记梳理,我们可以系统地了解变量作用域相关的知识点。 首先,我们需要明确变量作用域的两个基本类型:全局作用域和局部作用域...
6. **闭包**:闭包是一种特殊的函数,它可以访问其自身作用域、外部函数作用域以及全局作用域的变量,常用于封装私有变量和实现模块化。 7. **ES6及后续版本的新特性**:包括箭头函数、模板字符串、解构赋值、类...
在作用域分析的例子中,我们看到了变量作用域的另一个有趣方面。看下面这个例子: ```javascript var i = 0; // 定义全局变量i function test() { demoFunction(i); function innerFunction() { i = 1; // 局部...
JavaScript是Web开发中不可或缺的一部分,它是一种轻量级的解释型编程语言,广泛用于网页和网络应用。...继续深入学习,你将掌握更多高级特性,如作用域、闭包、原型链、异步编程等,进一步提升你的JavaScript技能。
- 闭包:闭包是一种特殊的作用域现象,可以访问并操作外部函数的变量,常用于实现私有变量和记忆化等功能。 5. **事件与DOM操作** - 事件处理:JavaScript可以监听和响应用户交互,通过addEventListener和...
- **变量作用域**: - 使用`var`声明的变量具有局部作用域,仅在其所在的函数内部可见。 - 没有使用`var`声明的变量具有全局作用域,在任何地方都可访问。 - **对象**: - **内建对象**:如`Math`、`Date`和`...
8. 闭包:闭包是函数及其词法环境的组合,它可以访问自身作用域、定义它的外部作用域甚至全局作用域的变量。例如,`function outer() { let x = 1; function inner() { console.log(x); } return inner; } let ...
闭包是JavaScript中另一个重要的特性,它允许函数访问并操作外部作用域的变量,即使在外部函数已经执行完毕后。闭包在模块化、异步编程和记忆化等场景下非常有用。 ```javascript function outerFunction(x) { ...
2. 作用域:JavaScript有两种作用域——全局作用域和局部作用域。函数内部声明的变量具有局部作用域,外部声明的为全局作用域。ES6引入了块级作用域,通过`let`和`const`关键字实现。 三、对象与数组 1. 对象:...
总的来说,韩顺平的JavaScript面向对象笔记详细地介绍了JavaScript中面向对象编程的关键概念和技术,包括变量作用域、对象引用、this的使用、对象的方法以及对象的构造和继承,这些都是理解和编写高效JavaScript代码...
JavaScript有全局作用域和局部作用域,函数内部创建的变量仅在函数内部可见。 八、异步编程 JavaScript的异步编程主要依赖回调函数、Promise和async/await。它们解决了JavaScript的单线程执行模型下避免阻塞UI的...
在"js第四天 js第四天笔记"这个主题中,我们可以深入探讨JavaScript的一些关键概念和特性,这些都是在学习过程中需要掌握的重点。 第一天到第四天的学习通常会涵盖JavaScript的基础知识,包括数据类型、变量、操作...
JavaScript中的作用域是编程中非常重要的概念,它决定了变量的可见性和生命周期。在JavaScript中,主要有两种作用域:全局作用域和局部作用域。 全局作用域是指在函数外部定义的变量,它们在整个脚本中都是可见的。...
闭包是一种特殊的作用域,它可以访问其自身、外部函数以及全局作用域的变量,即使在其定义的外部环境中,闭包依然能记住这些变量的状态。 6. **事件处理** JavaScript与用户的交互主要通过事件处理,如点击按钮、...
关于变量作用域,和IE,firefox对js的不同处理,这里有几个例子,有几个是原来从别处看到的记的笔记,有的是我自己挖掘出来的. 2.1 [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]2.2 [Ctrl+A 全选 注:如需引入...
JavaScript采用词法作用域,即变量的作用域由它们被声明的位置决定,而不是定义时的运行环境。闭包是一种特殊的内部函数,它可以访问外部函数的变量,即使外部函数已经执行完毕。这种机制在内存管理和创建私有变量时...
函数的作用域决定了变量的可见性,全局作用域的变量在整个程序中都可访问,而局部作用域的变量只在函数内部可用。 三、对象与原型 JavaScript中的对象是键值对的集合,可以通过对象字面量或构造函数创建。原型是...
总结,ES6的块级作用域绑定通过let和const关键字改变了JavaScript的变量管理方式,消除了var带来的潜在问题,提供了更精确的变量作用域,增强了代码的可读性和维护性。对于开发人员来说,理解并熟练运用这些新特性是...