JavaScript的作用域问题

JavaScript作用域应该是JavaScript里面最难理解的概念了。看了《JavaScript高级程序设计》和其他的书虽然费了很大力气看懂了,感觉解释的还是有点费解。正好在网上看到几个面试题可以用作用域解决,也方便了对它的理解。

1.JavaScript是单线程程序

和其他语言当初设计的时候不一样,JavaScript是单线程(一个时机段内只干一件事情),是不支持并发这个概念的。为什么会这样呢?可以这样理解,假如一个线程正在创建DOM对象,然后下面一个线程将DOM对象删除了,这样矛盾吗?另外一个问题就是现在很火的Node也是单线程。非常重要的是JavaScript的单线程对页面解析而言,从上到下。傻瓜式的执行。

2.JavaScript预解析机制

先来看一个程序的执行结果:

alert(a);//function a(){alert(4);}
var a = 1 ;
alert(a);//1
function a(){alert(2);}
alert(a);//1
var a = 3 ;
alert(a);//3
function a(){alert(4);}
alert(a);//3

JavaScript解析器在解析的代码的时候可以简单的分为两个步骤(结合上述代码):

第一步:遍历代码寻找var变量、function函数、参数

a.将所有的var变量设置为undefined

  • a = undefined

b.将所有的函数体赋值给函数指针

  • a = function a(){alert(2);}
  • a = function a(){alert(4);}

c.整合上述两个步骤,其中+-*/%等具有运算功能进行赋值,后面的会覆盖前面的,所以上面的a、b两个步骤执行完过后就剩下:

  • a = function a(){alert(4);}

第二步:逐行扫描代码

在逐行扫描的过程中,会随时查看第一步中计算的结果a = function a(){alert(4);} 同时我们知道运算符具有赋值功能,会修改变量的值,而函数不具有赋值的功能。执行第一行代码alert(a)发现第一步执行结果是a = function a(){alert(4);}所以alert(a)的结果是 function a(){alert(4);}扫描第二行var a = 1; 发现有=具有赋值功能可以修改变量的值从而将a变量修改为var a = 1;扫描第三行发现现在有var a = 1;所以alert(a)结果是1,扫描第四行代码function a(){alert(2);}发现是函数所以没有赋值的功能。无法修改变量的值。所以第五行代码alert(a)的执行结果是1。扫描第六行代码var a = 3 ;所以变量a被修改为var a = 3 ;第七行代码执行结果是3;扫描第八行代码发现是函数function a(){alert(4);}无法修改变量的值,所以下面alert(a)执行的结果是3,上面整个流程就分析完了。

(这里不探讨所谓的语法、词法这些编译原理方面的知识)

3.JavaScript作用域链的简单理解

先看下面这个笔试题目:

var str = ‘jQuery‘;
function fun(){
     alert(str);//jQuery
     str = ‘JavaScript‘;
 }
 fun();
 alert(str);//JavaScript

按照上面将的两步方法进行分析,第一步:先找var变量、function函数、参数

var str = undefined

fun = fun(){………..}

第二步:逐行扫描代码第一行将变量str修改为var str = ‘jQuery‘;第二行行数没有赋值功能,第六行是函数调用,只要发生函数调用,继续第一步寻找变量、函数和参数,发现没有var变量函数和参数,这个时候将向函数外层寻找变量,这就是作用域链的概念,里面没有继续向外层寻找变量。发现有变量var str = ‘jQuery‘;所以结果是jQuery,向下执行代码str = ‘JavaScript‘操作符号可以进行赋值,发现外部有str同名变量所以有var str = ‘JavaScript‘,所以最后一行执行结果是JavaScript

以上就是今天的内容,内容不多但是不是很好理解。建议多分析多思考。和实际案例结合。。。实践出真知!

相关文章

非常高兴和大家交流学习

自由转载,创意许可,请文章来源,来自这里

(http://blog.csdn.net/unikylin)

时间: 2024-10-20 06:40:32

JavaScript的作用域问题的相关文章

深入浅出JavaScript变量作用域

在学习JavaScript的变量作用域之前,我们应当明确几点: JavaScript的变量作用域是基于其特有的作用域链的. JavaScript没有块级作用域.赌王娱乐城 函数中声明的变量在整个函数中都有定义. 1.JavaScript的作用域链 首先看下下面这段代码: <script type="text/javascript"> var rain = 1;     function rainman(){     var man = 2;     function inn

javascript 的作用域

翻译自:http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html 如果以下代码执行,你知道出什么结果吗? var foo = 1; function bar(){ if(!foo){ var foo = 10; } alert(foo); } bar(); 这运行结果是10. 如果你对结果感到惊讶,请看下面例子: var a =1; function b(){ a = 10; return; function a(){}

JavaScript从作用域到闭包

作用域(scope) 全局作用域和局部作用域 通常来讲这块是全局变量与局部变量的区分. 参考引文:JavaScript 开发进阶:理解 JavaScript 作用域和作用域链 全局作用域:最外层函数和在最外层函数外面定义的变量拥有全局作用域. 1)最外层函数和在最外层函数外面定义的变量拥有全局作用域 2)所有末定义直接赋值的变量自动声明为拥有全局作用域,即没有用var声明的变量都是全局变量,而且是顶层对象的属性. 3)所有window对象的属性拥有全局作用域 局部作用域:和全局作用域相反,局部作

JavaScript 函数作用域的“提升”现象

在JavaScript当中,定义变量通过var操作符+变量名.但是不加 var 操作符,直接赋值也是可以的.例如 : message = "hello JavaScript ! " 即定义了一个全局变量message,并赋值 "Hello JavaScript!"--<JavaScript高级程序第三版> 如同往日一般,一群人在所谓的技术交流群里面相互斗图着.突然老王莫名的正经起来,在群里发了一道JavaScript的题目,让大家猜一猜这道题的答案. v

浅谈JavaScript的作用域

前段时间学了下JavaScript作用域,这个东西在JavaScript非常重要,也是JavaScript很基础的东西,正如少林里面基础武功,有了基础,才能学绝世武功. 作用域的作用是啥?一套设计良好的规则来存储变量,并且之后可以方便的找到这些变量. 就JavaScript里面的作用域来说,我总结有这么几个关键词: 1. 词法作用域 2. 函数作用域 3. 块级作用域 4. 闭包 5. 提升 好吧,我脑海里面能想到的就这么多了,不够的,也可以有朋友指出来,接下来,我一个一个过下这些词. 一.词法

JavaScript变量作用域

全部变量拥有全局作用域,局部变量拥有局部作用域(这里注意函数的参数也是局部变量) 1.在函数体内,局部变量的优先级高于同名的全局变量. 我的理解就是当你同时定义了同名的局部变量和全局变量时,函数体内返回的将是局部变量的值. 例如: var scope="我是全局变量"; function checkscope(){ var scope="我是局部变量"; console.log(scope); } checkscope(); 输出:我是局部变量 这里需要注意的是,在

JavaScript的作用域

JavaScript的作用域主要是指函数的作用域,在进行结果判断的时候十分重要,如果不清楚作用域,便很有可能导致拿不到预期的结果,也就无法顺利的进行程序的编写,在经历了一系列的学习和了解之后,对相关知识进行一个汇总,认识比较浅显,希望可以帮助到有需要的人. 首先引入一个概念:词法分析 JavaScript在创建的时候会对function进行词法分析,函数会在创建时形成一个活动对象,ActiveObject,简称AO,先举一个实际的例子进行分析: function t1(age) { consol

JavaScript中作用域链和闭包

一.匿名函数 1.1 匿名函数的概念 ? 声明一个没有函数名的函数,就是匿名函数. ? 有函数名的函数就是具名函数. 看下面的代码: <script type="text/javascript"> /* //这里定义了一个函数,而且没有函数名.这样写语法是错误的,如果允许这样定义,那么根本就没有办法调用. //所以,我们可以用一个变量来存储一下 function(){ } */ // 声明了一个匿名函数,并把匿名函数赋值给变量f. 注意这个时候这个匿名函数并没有执行. va

第一百零六节,JavaScript变量作用域及内存

JavaScript变量作用域及内存 学习要点: 1.变量及作用域 2.内存问题 JavaScript的变量与其他语言的变量有很大区别.JavaScript变量是松散型的(不强制类型)本质,决定了它只是在特定时间用于保存特定值的一个名字而已.由于不存在定义某个变量必须要保存何种数据类型值的规则,变量的值及其数据类型可以在脚本的生命周期内改变. 一.变量及作用域 1.基本类型和引用类型的值 ECMAScript变量可能包含两种不同的数据类型的值:基本类型值和引用类型值.基本类型值指的是那些保存在栈

JavaScript的作用域和提升机制

你知道下面的JavaScript代码执行时会输出什么吗? var foo = 1; function bar() { if (!foo) { var foo = 10; } alert(foo); } bar(); 答案是"10",吃惊吗?那么下面的可能会真的让你大吃一惊: var a = 1; function b() { a = 10; return; function a() {} } b(); alert(a); 这里浏览器会弹出"1".怎么回事?这似乎看起