首先说明一下:Js中的作用域不同于其他语言的作用域,要特别注意
 
 
JS中作用域的概念:

  表示变量或函数起作用的区域,指代了它们在什么样的上下文中执行,亦即上下文执行环境。Javascript的作用域只有两种:全局作用域和本地作用域,本地作用域是按照函数来区分的。

首先来看几道题目:

1.

复制代码
代码如下:
if(true){
var aa= "bb";
}

console.log(aa); //bb

for(var i = 0; i < 100; i++){
//do

}
console.log(i); //100

2.

复制代码
代码如下:
var bb = '11111';
function aa() {

alert(bb);//undefine
var bb = 'test';
alert(bb);//test
   var cc
= "test1";
alert(age);//语法错误
}
aa();

3.

复制代码
代码如下:
var test = '1111111';
function aa() {

alert(test);
}

function bb() {
var test = '22222222';

aa();
}

bb();//alert(1111111);

4.

复制代码
代码如下:
alert(typeof aa); //function

alert(typeof bb); //undefined function aa() { //函数定义式
alert('I am
111111111');
};
var bb = function() { //函数表达式
}
alert(typeof
bb);//function

5.

复制代码
代码如下:
function aa(){
var bb = "test";
cc
= "测试";
alert(bb);
}
aa();
alert(cc);//测试
alert(bb);//语法报错

上面这5道题目全部概括了js中作用域的问题

可以总结出这么几个观点

一、无块级作用域

从第一题中可以看出来,在{}中执行后,变量并没有被销毁,还是保存在内存中的,因此我们可以访问到的。

二、JavaScript中的函数运行在它们被定义的作用域里,而不是它们被执行的作用域里.

这里提到函数的作用域链这个概念,在ECMA262中,是这样的

任何执行上下文时刻的作用域, 都是由作用域链(scope
chain)来实现.
在一个函数被定义的时候, 会将它定义时候的scope chain链接到这个函数对象的[[scope]]属性.

在一个函数对象被调用的时候,会创建一个活动对象(也就是一个对象), 然后对于每一个函数的形参,都命名为该活动对象的命名属性,
然后将这个活动对象做为此时的作用域链(scope chain)最前端, 并将这个函数对象的[[scope]]加入到scope chain中.
所以题目3
结果是alert(1111111);

三、JS会提前处理function定义式 和var关键字

  如题目4
开始alert(bb); //undefine ,alert(age)//语法报错,这两个有什么区别呢,原因就是后面有var bb
=“test”,在初始化的时候提前处理了var 这个关键字,只是这个开始未赋值

将代码修改成这样的,可以看出来

复制代码
代码如下:
var dd = '11111';
function aa() {

alert(bb);//undefine
   var bb = 'test';
alert(bb);//test
   var
cc = "test1";
alert(age);//语法错误
}
aa();
alert(dd);//11111

alert(cc);//语法报错

此处alert(bb)没有报语法错误,alert(age)报语法错误。

但是请注意:

复制代码
代码如下:
<script>
alert(typeof aa);
//结果:undefined
</script>
<script>
function aa() {

alert('yupeng');
}
</script>

这说明js预编译是以段为单元的。题目4同理

四、函数级作用域

  函数里面的定义的变量,在函数执行完后就销毁了,不占有内存区域了。

  所以题目2最后的alert(cc);语法报错,题目5最后到 alert(bb)同理

浅谈javascript中的作用域的更多相关文章

  1. 浅谈javascript中变量作用域和内存(2)

    1.无块级作用域 javascript没有块级作用域,这会让其他程序员在理解js代码上很痛苦.在其他很多语言,比如C,大括号括起来的代码块都有自己的作用域 举个例子 if(true) { var na ...

  2. 浅谈javascript中变量作用域和内存(1)

    先理解两个概念:基本类型和引用类型的值 1.基本类型和引用类型的值 (1)定义: 基本类型:指简单的数据段,比如按值访问的js五种基本数据类型undefined.null.boolean.number ...

  3. 浅谈JavaScript中的闭包

    浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...

  4. 浅谈JavaScript中的null和undefined

    浅谈JavaScript中的null和undefined null null是JavaScript中的关键字,表示一个特殊值,常用来描述"空值". 对null进行typeof类型运 ...

  5. 浅谈JavaScript中的正则表达式(适用初学者观看)

    浅谈JavaScript中的正则表达式 1.什么是正则表达式(RegExp)? 官方定义: 正则表达式是一种特殊的字符串模式,用于匹配一组字符串,就好比用模具做产品,而正则就是这个模具,定义一种规则去 ...

  6. 浅谈JavaScript中的变量、参数、作用域和作用域链

    基本类型和引用类型 在JavaScript中有两种数据类型值.基本类型值和引用类型值.基本类型值指的是简单的数据段,而引用类型值指的是可能由多个值构成的对象.在JavaScript中有5种基本数据类型 ...

  7. 浅谈JavaScript中闭包

    引言 闭包可以说是JavaScript中最有特色的一个地方,很好的理解闭包是更深层次的学习JavaScript的基础.这篇文章我们就来简单的谈下JavaScript下的闭包. 闭包是什么? 闭包是什么 ...

  8. 浅谈JavaScript中的内存管理

    一门语言的内存存储方式是我们学习他必须要了解的,接下来让我浅谈一下自己对他的认识. 首先说,JavaScript中的变量包含两种两种类型: 1)值类型或基本类型:undefined.null.numb ...

  9. 浅谈JavaScript中的继承

    引言 在JavaScript中,实现继承的主要方式是通过原型链技术.这一篇文章我们就通过介绍JavaScript中实现继承的几种方式来慢慢领会JavaScript中继承实现的点点滴滴. 原型链介绍 原 ...

随机推荐

  1. Java 函数参数传递方式详解 分类: Java Game 2014-08-15 06:34 82人阅读 评论(0) 收藏

    转:http://zzproc.iteye.com/blog/1328591 在阅读本文之前,根据自己的经验和理解,大家可以先思考并选择一下Java函数的参数传递方式:  A. 是按值传递的?  B. ...

  2. HDOJ 1466 计算直线的交点数

    将n 条直线排成一个序列,直线2和直线1最多只有一个交点,直线3和直线1,2最多有两个交点,......,直线n 和其他n-1条直线最多有n-1个交点.由此得出n条直线互不平行且无三线共点的最多交点数 ...

  3. BZOJ2463: [中山市选2009]谁能赢呢?

    感慨下汉堡的找水题能力… /************************************************************** Problem: 2463 User: zhu ...

  4. 从底层理解Python的执行

    摘要:是否想在Python解释器的内部晃悠一圈?是不是想实现一个Python代码执行的追踪器?没有基础?不要怕,这篇文章让你初窥Python底层的奥妙. [编者按]下面博文将带你创建一个字节码级别的追 ...

  5. POJ 2010

    Moo University - Financial Aid Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 4235   A ...

  6. sream bytes[] img相互转换

    /// <summary> /// 将 Stream 转成 byte[] /// </summary> /// <param name="stream" ...

  7. sematext

    https://sematext.atlassian.net/wiki/display/PUBLOGSENE/Syslog

  8. Linux客户/服务器程序设计范式2——并发服务器(进程池)

    引言 让服务器在启动阶段调用fork创建一个子进程池,通过子进程来处理客户端请求.子进程与父进程之间使用socketpair进行通信(为了方便使用sendmsg与recvmsg,如果使用匿名管道,则无 ...

  9. 关于WII光枪定位的设计(转)

    方法1. 简单1 LED方法 这是一个很忽悠的方法,把LED看成是屏幕中心,把光枪摄像头的视野范围看作是屏幕范围. 假设WII枪头摄像头的数据范围为[0,1024]*[0,768],显示器屏幕分辨率为 ...

  10. 李洪强iOS开发之计算数组的最大最小值

    // //  ViewController.m //  A21 - 李洪强 - 输出参数 // //  Created by vic fan on 16/7/3. //  Copyright © 20 ...