1、作用域

  作用域,它是指对某一变量和方法具有访问权限的代码空间。当我们在定义变量的时候,会定义两种变量,一种是在全局环境下定义的变量,叫全局变量,一种是在函数中定义的变量叫局部变量。全局变量的作用域就是全局环境,局部变量的作用域就是函数。

2、作用域链

  javascript高级程序设计书中写到,当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终都是当前执行的代码所在环境的变量对象。 作用域链中的下一个变量对象来自包含(外部)环境,而再下一个变量则来自下一个包含环境,这样一直延续到全局执行环境;全局执行环境的变量对象始终都是作用域链中的最后一个对象。

  简单来说就是,当我查找一个变量时,我会先在自己所在的环境找,找不到延着作用域链继续向外一层的环境找,找不到再向外找,一直找到全局执行环境中。

  看一小段代码:

  

 var colorA = "red";
function abc(){
var colorB = "blue";
function info(){
var color ="yellow";
console.log(colorA);-------1
console.log(colorB);-------1
console.log(colorC);-------1
};
info();
console.log(colorA);-------2
console.log(colorB);-------2
console.log(colorC);-------2
};
abc();
console.log(colorA);-------3
console.log(colorB);-------3
console.log(colorC);-------3

  在上述代码中,你可以发现,标记为1的,三个颜色A、B、C都能正确的被找到并打印出来。而标记为2的,只能找到A、B颜色。而标记为3的,只能够找到A颜色。

  出现这种情况的原因就是去查找变量值的时候,是先从自身所在的环境中查找,没找到的时候,沿着作用域链向外层查找,所以在内层可以访问到外层定义的变量,在外层是访问不到内层所定义的变量的。

3、块级作用域和函数作用域

  我们都听说过javscript是没有块级作用域的,javascript执行的是函数作用域,那么什么是块级作用域呢?

  任何一对花括号({和})中的语句集都属于一个块,在这之中定义的所有变量在代码块外都是不可见的,我们称之为块级作用域。

  什么是函数作用域?

  简单来说函数中的参数和变量在函数外部是不可见的,只在函数内部可以访问。

  为什么说javascript没有块级作用域,看一段以下代码:

  

 var color="red";
if(true){
var color = "blue";
console.log(color);
}
console.log(color);

  会发现两个输出的都是blue,如果有块级作用域的话,if里面的color会被当做局部变量创建,这样子的话输出的就是"blue","red"了;正是因为没有块级作用域,if里面对color的赋值被当做是全局变量把原来的值覆盖掉,所以输出才会是两个都是blue;

4、变量声明提升

  先来看一小段代码,你认为的输出是什么:

  

 var a = 100;
function testResult(){
var b = 2 * a;
var a = 200;
var c = a / 2;
console.log(b);
console.log(c);
}
testResult();

  我们先不管上面的输出是什么,先来看看这几行代码的输出是什么;

  console.log(a);var a = 123;  //undefined;

  console.log(a);var a ;  //undefined;

  var a = 123;console.log(a);   //123;

  出现这种情况就是因为变量声明提升,我们去声明一个变量的时候javascript引擎会把变量"提前"声明,而把赋值放在原来的顺序。

  所以console.log(a);var a = 123;的执行顺序其实是var a; console.log(a); a = 123;

  故输出a的时候只是创建了变量还没有被赋值,所以输出为undefined;

  现在再来看看刚那段代码的执行顺序其实是:

  

 var a = 100;
function testResult(){
var b;
var a;
var c;
b = 2 * a; //此时在局部变量中找到了a,故不会再向上找全局变量a = 100; 但是a还没被赋值,a为undefined,故此时b为NaN;
a = 200;
c = a / 2; // 100;
console.log(b); //NaN
console.log(c); //100
}
testResult();

注:对undefined作加减乘除会把它转化为数字类型,undefined转化为数字类型就是NaN;

故输出为 NaN 和 100 ;

  

javascript作用域和作用域链的更多相关文章

  1. 深入理解 JavaScript 变量的作用域和作用域链

    一个变量的作用域(scope)是程序源代码中定义这个变量的区域.简单的说,作用域就是变量与函数的可访问范围.全局变量拥有全局作用域,在JavaScript代码中的任何地方都有定义.局部变量是在函数体内 ...

  2. 一步步学习javascript基础篇(2):作用域和作用域链

    作用域和作用域链 js的语法用法非常的灵活,且稍不注意就踩坑.这集来分析下作用域和作用域链.我们且从几道题目入手,您可以试着在心里猜想着答案. 问题一. if (true) { var str = & ...

  3. 关于Javascript作用域及作用域链的总结

    本文是根据以下文章以及<Javascript高级程序设计(第三版)>第四章相关内容总结的. 1.Javascript作用域原理,地址:http://www.laruence.com/200 ...

  4. javascript篇-----函数作用域,函数作用域链和声明提前

    在一些类似C语言的编程语言中,花括号内的每一段代码都具有各自的作用域,而且变量在声明它们的代码段之外是不可见的(也就是我们不能在代码段外直接访问代码段内声明的变量),我们称之为块级作用域,然而,不同于 ...

  5. javascript笔记:javascript的关键所在---作用域链

    javascript里的作用域是理解javascript语言的关键所在,正确使用作用域原理才能写出高效的javascript代码,很多javascript技巧也是围绕作用域进行的,今天我要总结一下关于 ...

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

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

  7. javascript作用域和作用域链摘录

    作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域链的工作原理.今天这篇文章对JavaScript作用域和作用域链作简单的介绍,希望 ...

  8. JavaScript高级之词法作用域和作用域链

    主要内容: 分析JavaScript的词法作用域的含义 解析变量的作用域链 变量名提升时什么 一.关于块级作用域         说到JavaScript的变量作用域,与咱们平时使用的类C语言不同. ...

  9. JavaScript 开发进阶:理解 JavaScript 作用域和作用域链

    作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域链的工作原理.今天这篇文章对JavaScript作用域和作用域链作简单的介绍,希望 ...

  10. JavaScript 开发进阶:理解 JavaScript 作用域和作用域链(转载 学习中。。。)

    作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域链的工作原理.今天这篇文章对JavaScript作用域和作用域链作简单的介绍,希望 ...

随机推荐

  1. event对象具有的方法

    // dataTransfer,toElement,fromElement,y,x,offsetY,offsetX,webkitMovementY,webkitMovementX,relatedTar ...

  2. java并发编程_建立概念

    在学习多线程编程时,相信大家会遇到好多概念类的东西,对于这些概念的不准确理解会导致后面越学越糊涂,现将学习过程中遇到的概念整理到这篇博客上,一来记录学习点滴,二来也加深理解,如果有理解不准确的地方,希 ...

  3. 消息机制2 - Windows程序设计(SDK)005

    消息机制2 让编程改变世界 Change the world by program 内容节选: 关于消息机制,还有三点需要补充: 消息队列是FIFO的形式 WM_PAINT,WM_TIMER 和 WM ...

  4. VC中如何获取当前时间(精度达到毫秒级)

    标 题: VC中如何获取当前时间(精度达到毫秒级)作 者: 0xFFFFCCCC时 间: 2013-06-24链 接: http://www.cnblogs.com/Y4ng/p/Millisecon ...

  5. JAVA三大特性之多态

    面向对象的三大特性:封装.继承.多态.从一定角度来看,封装和继承几乎都是为多态而准备的.这是我们最后一个概念,也是最重要的知识点. 多态的定义:指允许不同类的对象对同一消息做出响应.即同一消息可以根据 ...

  6. windows下adb+flash_image刷机

    刷机是常事,总要把刷机包放在卡上,然后关机三键一起按到recovery再刷,觉得不爽,麻烦,所以研究出了adb调用flash_image刷system分区,全部脚本windows脚本执行,点点鼠标就o ...

  7. 【转】使用 vim + ctags + cscope + taglist 阅读源码

    原文网址:http://my.oschina.net/u/554995/blog/59927 最近,准备跟学长一起往 linux kernel 的门里瞧瞧里面的世界,虽然我们知道门就在那,但我们还得找 ...

  8. poj1014:母函数+优化

    题目大意: 有1~6六种宝石,价格分别为1~6 ..给定每种宝石的个数,问能否平分给两个人 分析: 一看显然是个多重背包问题,也可以用母函数做 不过母函数的复杂度是n*v*k,第一次tle了.. 后来 ...

  9. python字符串(移除空白,长度,索引,分割,切片,拼接,格式化输出)

    常用功能: 移除空白: >>> name = "meng" >>> name 'meng' >>> name.strip() ...

  10. 关于win8开发的一点小总结

    我今天做画面的时候,发现了一点小问题. 我在xmal文件里面加了一个CheckBox控件,设置IsChecked属性为True,并添加了Checked事件.Checked事件里面有对另外一个TextB ...