js 中采用词法作用域

所谓的 词法( 代码 )作用域, 就是代码在编写过程中体现出来的作用范围. 代码一旦写好, 不用执行,

作用范围就已经确定好了. 这个就是所谓词法作用域.

在 js 中词法作用域规则:

1.函数允许访问函数外的数据.

2.整个代码结构中只有函数可以限定作用域.

3.作用规则首先使用提升规则分析.

4.如果当前作用规则中有名字了, 就不考虑外面的名字.

在编译语言中,**通常** 代码在被引擎执行之前会经历三个步骤:

1. 词法分析(tokenzing/lexing)
2. 解析/语法分析(parsing)
3. 代码生成

而 Javascript 则是在运行时编译,边编译边执行,这个机制涉及到三样东西:

1. 引擎
2. 编译器
3. 作用域

编译器首先对代码进行编译,然后将生成的代码提供给引擎执行。引擎和编译器工作的时候,都会用到作用域。编译器编译时,会在作用域中查找标示符,如果没有找到的话则会在对应的作用域创建一个标示符。引擎在执行时不断的在作用域中查找标示符,如果一直到全局对象(Global object)都没有找到的话则抛出一个 `Reference Error` 并停止代码的执行。

主要来看一下作用域,作用域有两种主要的工作模式:词法作用域和动态作用域。大多数标准语言编译器的第一个工作阶段叫做词法化,词法作用域就是定义在词法阶段的作用域。换句话说,词法作用域是根据你写代码时变量和块作用域写在哪里来决定的,和你使用/调用的位置无关。

看几个例子:

A

var num = 123;
function f1() {
console.log( num );
}
function f2() {
var num = 456;
f1();
}
f2();
结果输出123

B

var num = 123;
function f1() {
console.log( num );
}
function f2() {
num = 456;
f1();
}
f2();

结果输出456

C

function b () {

var a = a || 2;
console.log(a);
}
var a = 1;
b() // 2

结果输出2

时间: 2024-07-30 07:13:39

js 中采用词法作用域的相关文章

JS中的嵌套作用域

在JS中仅仅区分全局变量和局部变量还不够,实际上,变量作用域可以有任意层级(嵌套).其他函数内部定义的函数可以调用父函数的局部变量,而内部函数里定义的函数则不仅可以调用父函数的局部变量,还可以调用祖父函数的局部变量. //定义一个函数接收正数number,然后将其和参数factor相乘 function multiplyAbsolute(number,factor){ function multiply(number){ return number*factor; } if (number<0)

js 词法分析,词法作用域

先来看个常见的面试题如下: var a = 10; function test(){ alert(a); //undefined var a = 20; alert(a); //20 } test(); 疑问:为什么呢?test()执行时,虽然a=20没有赋值,但是父级作用域里是有a=10的,不应该是undefined呀,js是按顺序执行的,此时的var num = 20;根本没有执行,所以应该是10!!你是不是也是这么认为的,就和我当初一样??? 分析:众所周知,js代码是自上而下执行的,Ja

js中的变量作用域问题

变量既可以是全局的,也可以是局部的. 全局变量可以在脚本的任何位置被引用.一旦你在脚本里声明了一个全局变量,就可以从这个脚本中的任何位置--包括函数内部引用它.全局变量的作用域是整个脚本. 局部变量只存在于声明它的那个函数的内部,在那个函数的外部是无法引用它的.局部变量的作用域仅限于某个特定的函数. 注意:在js中块级别中用var声明的变量也是全局变量. 如果在一个函数中使用了var声明一个变量,那么这个变量就是一个局部变量,它只存在于函数的上下文中.如果没用使用var声明一个变量,而是直接写了

js中三种作用域详解(全局,函数,块级)

1.全局变量:声明在函数外部的变量(所有没有var直接赋值的变量都属于全局变量) 2.局部变量:声明在函数内部的变量(所有没有var直接赋值的变量都属于全局变量) JS中变量申明分显式申明和隐式申明. vari=100;//显式申明 i=100;//隐式申明 在函数中使用var关键字进行显式申明的变量是做为局部变量,而没有用var关键字,使用直接赋值方式声明的是全局变量. 当我们使用访问一个没有声明的变量时,JS会报错.而当我们给一个没有声明的变量赋值时,JS不会报错,相反它会认为我们是要隐式申

深入理解JS中的变量作用域

在JS当中一个变量的作用域(scope)是程序中定义这个变量的区域.变量分为两类:全局(global)的和局部的.其中全局变量的作用域是全局性的,即在JavaScript代码中,它处处都有定义.而在函数之内声明的变量,就只在函数体内部有定义.它们是局部变量,作用域是局部性的.函数的参数也是局部变量,它们只在函数体内部有定义. 我们可以借助JavaScript的作用域链(scope chain)更好地了解变量的作用域.每个JavaScript执行环境都有一个和它关联在一起的作用域链.这个作用域链是

对js中闭包,作用域,原型的理解

前几天,和朋友聊天,聊到一些js的基础的时候,有一种‘好像知道,好像又不不知道怎么讲的感觉’...于是捡起书,自己理一理,欢迎拍砖. 闭包 理解闭包首先要理解,js垃圾回收机制,也就是当一个函数被执行完后,其作用域会被收回,如果形成了闭包,执行完后其作用域就不会被收回. 如果某个函数被他的父函数之外的一个变量引用,就会形成闭包 闭包的作用,就是保存自己私有的变量,通过提供的接口(方法)给外部使用,但外部不能直接访问该变量. 例子(使用闭包): var test=(function(){ var

js中变量、作用域及内存

一.变量及作用域 1.基本类型和引用类型的值 ECMAScript变量可能包含两种不同的数据类型的值:基本类型值和引用类型值.基本类型值指的是那些保存在栈内存中的简单数据段,即这种值完全保存在内存中的一个位置.而引用类型值则是指那些保存在堆内存中的对象,意思是变量中保存的实际上只是一个指针,这个指针指向内存中的另一个位置,该位置保存对象. 将一个值赋给变量时,解析器必须确定这个值是基本类型值,还是引用类型值.基本类型值有以下几种:Undefined.Null.Boolean.Number和Str

Js中变量的作用域

一.理解函数作用域需要理解以下几点:    1.函数变量的作用域有全局变量和局部变量两种,全局变量写在函数的最前面,局部变量写在函数体内,局部变量省略了var 也就默认成为了全局变量!    2.函数体内部可以读取到函数外的变量,而函数外不能读取到函数内的变量! 在理解了函数变量的作用域之后,也需要理解函数的作用域链了:    1.每一个函数都有一个与之相关的作用域链,当js在查找变量X时,它会从链的第一个对象开始查找,如果这个对象有一个名为X的属性值,则会直接使用这个 属性值,如果没有就继续下

js中理解函数作用域的实例

一.Javascript的变量的scope是根据方法块来划分的(也就是说以function的一对大括号{ }来划分).切记,是function块,而for.while.if块并不是作用域的划分标准,可以看看以下几个例子:           1 <script type ="text/javascript" > 2 function test2(){ 3 alert ("before for scope:"+i); // i未赋值(并不是未声明!使用未声