Javascript学习笔记3 作用域_基础知识

在Javascript,全局环境本身就一个对象。在浏览器宿主中这个对象是window,而当Javascript用于其它非浏览器的宿主,如嵌入式的环境中,可能会是其它的对象。
在这里也纠正一个观念,有很多人都认为Javascript只在浏览器中使用,其实Javascript也能在很多非Web情况下使用,据介绍Javascript在一些基于嵌入式的应用领域表现得也很出色,当然这些我也只是听过传说而已。
言归正传,当我们写下:var i=1时,其实就是声明了一个window作用域的一个变量。
而当我们写下i=1时,是声明了一个window的属性。
看这样一段代码:

[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

这段代码分别输出的结果是:undefined world,welcome china, hello china.
我们来分别解释:
在上文中,我们说过,在Javascript预编译时,会把所有var变量创建,默认值为undefined,我们在这里可以举一个例子:
我们可以写这样一段代码:

[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

当我们执行运行这段脚本时,可以发现,首先弹出undefined,然后回提示脚本错误,提示b不存在。由此就可以表明,a在预编译的过程中就已经被创建并且初始化为undefined,而b却只能在实际运行时按顺序去解释。其实在预编译后的Javascript代码可以近乎理解如下:

[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

接下来我们可以谈一下函数的作用域问题,每当代码运行进入一个函数时,Javascript引擎就会自动创建一个新的作用域,然后把这个新作用域作为当前作用域的子作用域,然后把当前的代码作用域切换到这个新作用域。当代码退出函数时,这个作用域销毁,把代码作用域交还给他的父作用域。
好,准备工作差不多了,接下来我们就来解释第一个问题:问什么会输出undefined world。
首先代码进行在预编译,当进入 Test方法时,开启一个新作用域,然后把全局作用域作为他的父作用域。然后对Test内的方法进行预编译,和上面的代码一样,Test方法被预编译后方法体大致如下:

复制代码 代码如下:

function Test() {
var a = undefined;
alert(a + " " + b);
var a = "welcome";
b = "china";
alert(a + " " + b);
}

当然,在当前作用域下无法找到b,于是他就会到他的父作用域下,也就是全局作用域找到了b=“world”。于是也就产生了这样的结果。
第二次弹出welcome china,没什么好说的。
第三次,弹出hello china。我们可以这样理解,var a 只是 方法Test的一个局部变量,而b由于事先未声明,因此他会去父作用域中去找到对应的定义。
好,接下来,我们再看一下这个方法的若干个变体。

[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

首先,我们将方法体内的var a改成a,我们先不看答案,直接来分析,首先,在预编译阶段,方法体内几乎没有任何改变,因此此时a和b一样,都要去他们的父作用域中去寻找,因此第一次出的结果应该是hello world,第二次没什么说的:welcome china,第三次由于a和b在本作用域内都没有事先定义,因此都是再改变父作用域内的值,因此应该输出welcome china.
我们继续:

[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

和上面的分析一样,应该输出undefined undefined,welcome china,hello world.
继续:

[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

应该是undefined world,welcome china,hello china.
经试验,都没问题, 不知道你明白了么?
因此我们可以得出,每个变量在找不到自己的定义时,都会沿着作用链向上寻找,这样就很可能会出现未预知的错误,给排错添加了很多困难。更麻烦的是,还可能会对父作用域上的变量值进行修改,因此我们在声明变量时应该尽量加上var,尽管Javascript并不强迫我们这样做。

时间: 2024-09-26 12:53:19

Javascript学习笔记3 作用域_基础知识的相关文章

JavaScript 学习笔记之语句_基础知识

一.条件分支语句:if 基本格式: if (<表达式1>){     <语句组1> }else if (<表达式2>){     <语句组2> }else{     <语句组3> } 执行流程: 二.循环语句 2.1前测试循环语句:在循环体内的代码被执行之前就对出口条件求值. 2.1.1while语句 基本格式: do {     <语句组> } while (<表达式>) 执行流程: 2.1.2 for语句 基本格式:

JavaScript 学习笔记之操作符_基础知识

一.一元操作符 1.自增自减操作符:分为前置型和后置型: 前置型:++a;--a; 后置型:a++;a--; 例: 复制代码 代码如下:    <script type="text/javascript">          var a, b,i= 1,j=1;          a=i++;          b=++j;          alert("a="+a+",i="+i+",b="+b+",

JavaScript 学习笔记之数据类型_基础知识

一.分类 基本数据类型:undefined.null.string.Boolean.number 复杂数据类型:object object的属性以无序的名称和值对的形式 (name : value) 来定义 二.详解 1.undefined:undefined类型只有一个值:undefined,在使用var对变量进行声明但未初始化时,这个变量的值就是undefined. 包含undefined值的变量与尚未定义的变量是不一样的,以下这个例子可以说明: 复制代码 代码如下:     var dem

Javascript学习笔记1 数据类型_基础知识

代码类型只有一种形式就是function. undefined:未定义,我们也可称之为不存在,typeof(undefined)=undefined. null:为空.undefined是不存在,而null是存在,但却无.typeof(null)=object,但null又不是object,这就是null的神奇而独特之处. boolean:true or false. Number:NaN和Infinity是两个特殊之数,NaN代表一个无法用数值来表示的数字,而Infinity代表一个无穷大的数

Javascript学习笔记2 函数_基础知识

就像我们可以写成这样的形式一样: 复制代码 代码如下: function Hello() { alert("Hello"); } Hello(); var Hello = function () { alert("Hello"); } Hello(); 其实都是一样的. 但是当我们对其中的函数进行修改时,会发现很奇怪的问题. 复制代码 代码如下: <script type="text/javascript"> function Hel

JavaScript学习笔记之定时器_基础知识

定时器1 用以指定在一段特定的时间后执行某段程序. setTimeout(): 格式:[定时器对象名=] setTimeout("<表达式>",毫秒) 功能:执行<表达式>一次. 例子: 复制代码 代码如下: <!DOCTYPE html> <html>   <head>     <title>timer1.html</title>     <meta http-equiv="keywo

Javascript 读书笔记索引贴_基础知识

一. 基础篇 Javascript学习笔记1 数据类型 Javascript学习笔记2 函数 Javascript学习笔记3 作用域 Javascript学习笔记4 Eval函数 Javascript学习笔记5 类和对象 Javascript学习笔记6 prototype的提出 Javascript学习笔记7 原型链的原理 二. 实战篇Javascript学习笔记8 用JSON做原型 Javascript学习笔记9 prototype封装继承

javascript学习笔记(一)基础知识_基础知识

基本概念 javascript是一门解释型的语言,浏览器充当解释器. js执行引擎并不是一行一行的执行,而是一段一段的分析执行. 延迟脚本 HTML4.0.1中定义了defer属性,它的用途是表明脚本在执行时不会影响页面的构造.也就是说,脚本会延迟到整个页面都解析完毕后再执行.因此,在<script>元素中设置defer属性,相当于告诉浏览器立即下载,但延迟执行.在XHTML文档中,要把defer属性设置为defer="defer" 异步脚本 html5为<scrip

javascript函数作用域学习示例(js作用域)_基础知识

在一些类似c语言的编程语言中,花括号内的每一段代码都具有各自的作用域,而且变量在声明他们的代码段之外是不可见的,我们称为块级作用域(block scope),而javascript中没有块级作用域.取而代之的javascript使用的是函数作用域(function scope):变量在声明它的函数体以及这个函数体嵌套的任意函数体内都是有定义的. 在如下代码中,在不同位置定义的i,j和k,他们再同一个作用域内都是有定义的 复制代码 代码如下: function text(o)   {