JavaScript函数之作用域 / 作用链域 / 预解析

关于作用域和作用链域的问题,很多文章讲的都很详细,本文属于摘录自己觉得对自己有价值的部分,留由后用,仅供参考,需要查看详细信息请点击我给出的原文链接查看原文件

做一个有爱的搬运工~~

-------------------------------------------------------------------------------------------------------------------------------------------

作用域

js中作用域只有一种,就是函数作用域,除此之外,还存在一种作用域叫块作用域,但在此之前,想先说一下什么叫做块

  

  在JAVA或者C中(因为我只学过这两种语言),块就是写在{}中的语句,一般看作一条语句执行,

  块作用域(JS中不存在块作用域的概念)

  在块中的语句对块外是封闭的,在JAVA和C中都有这样的特性

  例如

//JAVA 代码
public class Block {
    public static void main(String[] args) {
        if(true){
            int i = 9;
        }
        System.out.println(i);//代码报错
    }
}
//以上的代码编译时会报错,强制编译并执行时会抛出以下的错误:
//Exception in thread "main" java.lang.Error: Unresolved //compilation problem: i cannot be resolved to a variable

  所以,JAVA是有块作用域的概念的,同样的代码,放在JS中时

//JavaScript代码
function fun(){
        if(true){
                var i = 9;
        }
        return i;
}
fun();//输出 9

  这就说明, 在if语句中声明的变量在if语句之后被保留在内存中了,并没有销毁.

  需要特别说明的是:JS中,在函数中用var定义的变量是局部变量,不用var定义的变量会默认作为全局变量使用

function f1(){
        var n=9;
        m = 10;
}
f1();
console.log(n);//不会输出结果,报错误:ReferenceError: n is not defined, 意思是该变量未定义
console.log(m);//输出10

  关于这个说法,在很多文章中都有提及,比如 Javascript中模仿块级作用域  : 其中对JS中作用域的解释说:使用var关键字声明变量时,这个变量会自动添加到距离最近的可用环境中。对于函数而言,这个最近的环境就是函数的局部环境。如果变量在未经声明的情况下被初始化,则该变量会被自动添加到全局环境。

在JS中实现块作用域的使用效果

同样在  Javascript中模仿块级作用域 这篇文章中,利用匿名函数来实现块作用域的功能

(function(){

    //块级作用域

})();//来自原文的话: 这种技术常在全局作用域中用在函数外部,来限制向全局作用域中添加过多的变量和函数。当然,只要我们临时需要一些变量,都可以使用块级作用域(私有作用域)。当匿名函数执行完毕,其作用域链立即销毁,从而可以减少闭包占用资源问题。

  在这里再贴一个也比较好的说明作用域知识的文章 js作用域问题一步步透彻理解

  这篇文章中,有这样一个例子(这个细节是我之前并没有注意过的>>细节指数:★★★★)

function fun(){
        var a = b = 10;
}
console.log(a);//ReferenceError: a is not defined
console.log(b);//输出: 10
/*
 *原文的话:  var a = b = 10; 这种写法在函数内: b其实是全局变量,a当然是局部变量
 */

  所以我自己给出了下面的例子

function fun(){
        var a = 10, b = 10;
}
console.log(a);//ReferenceError: a is not defined
console.log(b);//ReferenceError: b is not defined
/*
 *a是局部变量
 *b是局部变量
 *我们可以很清楚的知道, var a = 10, b = 10; 这种写法在函数内是定义局部变量的有效方法,
 */

-----------------------------------------------------------------------------------------------------------------------

作用链域

  预解析(在说作用链域之前,我想先说一个问题---预解析,先给出引用的文章地址, 方便回溯)

  解释一下啥叫预解析(自己起的名),希望给一些初学js的提供些帮助

  说法:js引擎读取一段js代码,首先预解析(这个名字我起的),就是逐行读取js代码,寻找全局变量和全局函数,遇到全局变量,把变量的值变为undefind,存在内存中,遇到全局函数,直接存在内存中,这个过程如果发现语法错误,预解析终止。

  当预解析完成后,js引擎在从第一行开始逐行运行js代码。

  js的预解析

  说法:js的预解析是在程序进入一个新的环境时,把该环境里的变量或函数预解析到它们能调用的环境中。即每一次预解析的单位是一个执行环境。

  转:javascript(js)预解析原理

  说法:函数预解析

  1、javascript在执行前会进行类似“预解析”的操作:首先会创建一个在当前执行环境下的活动对象,并将那些用var 声明的变量、定义的函数设置为活动对象的属性,但是此时这些变量的赋值都是undefined。

  2、在javascript解释执行阶段,遇到变量需要解析时,会首先从当前执行环境的活动对象中查找,如果没有找到‍而且该执行环境的拥有者有prototype属性时则会从prototype链中查找,否则将会按照作用域链查找。遇到var a = …这样的语句时会给相应的变量进行赋值(注意:变量的赋值是在解释执行阶段完成的,如果在这之前使用变量,它的值会是undefined)。

//预处理的例子

console.log(a);//输出: undefined
console.log(b);//输出: undefined
console.log(c);//输出: function c(){return "C";}

var a = "A";
var b = function(){return "B"; }
function c(){return "C";}

//在语法分析阶段,a保存用var进行显示声明的局部变量,并且置默认值为undefined,这里就是上述代码中"console.log(a)"输出为undefined的原因,由于代码在语法分析阶段就已经保留了标记符a,在赋值语句"var a = "A"; "执行之前a的值都是undefined,因此在"console.log(a)"的时候就显示为undefined了。(修改引用自:(转载)浅谈JavaScript的闭包和作用域链)

  至此,如果预解析的概念有所了解了(其实我还没有完全理解,疑问就是:上例中的b和c的输出结果为什么不一样???如果有人理解,可以评论告诉我,不胜感激),就可以来说说作用链域的事儿了.

  作用链域

  看看这篇文章:  (转载)浅谈JavaScript的闭包和作用域链(这篇文章讲了很多机制性的东西,个人觉得比较好!!!)

  原文:作用域链(scope chain)就是由作用域组成的链,是一个类似链状的数据结构。作用域就是对上下文环境的数据描述。闭包和作用域链是紧密关系的,函数实例执行时的闭包是构成作用域链的基本元素。JavaScript代码在执行前会进行语法分析,在语法分析阶段,会记录全局环境中的变量声明和函数定义,构造函数的调用对象(Call Oject、Activation Object、Activate Object、活动对象,不同称呼罢了)和在全局环境下的作用域链。

  [  关于闭包的内容我会在下一篇文章  JavaScript函数之闭包  中具体来说  ]

  至于作用链域的其他知识点,我感觉没有办法总结的比文章(转载)浅谈JavaScript的闭包和作用域链要好,所以,不多说,看原文!

--------------------------------------------------------------------------------------------------------------------------

参考文章:

Javascript中模仿块级作用域

js作用域问题一步步透彻理解

解释一下啥叫预解析(自己起的名),希望给一些初学js的提供些帮助

js的预解析

转:javascript(js)预解析原理

(转载)浅谈JavaScript的闭包和作用域链

时间: 2024-10-20 16:34:53

JavaScript函数之作用域 / 作用链域 / 预解析的相关文章

javascript函数以及作用域简介

javascript函数以及作用域简介 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.基本函数 对于JavaScript中函数参数,实际参数的个数可能小于形式参数的个数,函数内的特殊值arguments中封装了所有实际参数.JavaScript中函数基本上可以分为以下三类: 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8&

JavaScript函数,作用域以及闭包

JavaScript函数,作用域以及闭包 1. 函数 (1). 函数定义:函数使用function关键字定义,它可以用在函数定义表达式或者函数声明定义. a. 函数的两种定义方式: * function functionName() {} * var functionName = function(){} b. 两种函数定义不同之处 1). 声明提前问题 函数声明语句   :声明与函数体一起提前 函数定义表达式 :声明提前,但是函数体不会提前 请看下面图示:绿色线上面实在js初始加载的时候,查看

JavaScript之作用域,作用域链和预解析

变量包括:全局变量,局部变量 在JAvaScript中,函数中定义的变量是局部变量 作用域:就是变量的使用范围, 分为:局部作用域和全局作用域 js中没有块级作用域---一对括号中定义的变量,这个变量可以在大括号外面使用 作用域链:变量的使用,从里向外,层层的搜索,搜索到了就可以直接使用了 var num=10; //作用域链 级别:0 var num2=20; var str = "abc" function f1() { var num2=20; function f2() { v

JavaScript函数及作用域

知识内容: 1.JavaScript函数 2.JavaScript作用域 参考资料:<JavaScript高级程序设计> 一.JavaScript中的函数 1.函数的定义 学完python后,对函数的定义一定不再陌生了,函数对于任何一个语言来说都是核心的概念.通过函数我们可以封装任意多条语句,而且可以在任何地方任何时候调用执行.JavaScript中的函数使用function来声明定义,函数的基本语法如下: 1 function functionName (arg0, arg1, ..., a

作用域和作用域链及预解析

//变量---->局部变量和全局变量, //作用域:就是变量的使用范围 //局部作用域和全局作用域 //js中没有块级作用域---一对括号中定义的变量,这个变量可以在大括号外面使用 //函数中定义的变量是局部变量 // 作用域链:变量的使用,从里向外,层层的搜索,搜索到了就可以直接使用了 // 层层搜索,搜索到0级作用域的时候,如果还是没有找到这个变量,结果就是报错 var num=10; var num=20; var str="abc"; function f1(){ var

javascript函数及作用域的小结

在js中使用函数注意三点:1.函数被调用时,它是运行在他被声明时的语法环境中的: 2.函数自己无法运行,它总是被对象调用的,函数运行时,函数体内的this指针指向调用该函数的对象,如果调用函数时没有明确指定该对象, this 默认指向 window ( strict 模式除外,本文不涉及 strict 模式): 3.函数是一种带有可执行代码的对象类型数据. 一.声明函数 1.使用 function 关键字 代码如下: function myfun(a,b){ //声明名为myfun的函数 ret

javascript 函数和作用域(六)

重点. 一.函数 函数是一块JavaScript代码,被定义一次,但可执行和调用多次.JS中的函数也是对象,所以JS函数可以像其他对象那样操作和传递,所以我们也常叫JS中的函数为函数对象. 注意: 函数的返回值,依赖于return语句. 一般的函数调用:如果没有return语句的话,默认会在所有代码执行完以后返回undefined. 如果是作为构造器,外部使用new去调用的话,如果没有return语句,或者return的是基本类型的话,默认会将this作为返回. 反之,如果return的是对象,

javascript 函数及作用域总结介绍

在js中使用函数注意三点: 1.函数被调用时,它是运行在他被声明时的语法环境中的: 2.函数自己无法运行,它总是被对象调用的,函数运行时,函数体内的this指针指向调用该函数的对象,如果调用函数时没有明确指定该对象, this 默认指向 window ( strict 模式除外,本文不涉及 strict 模式): 3.函数是一种带有可执行代码的对象类型数据. 一.声明函数 1.使用 function 关键字 代码如下: function myfun(a,b){ //声明名为myfun的函数 re

JavaScript 函数和作用域(作用域)

作用域:它是指对某一变量和方法具有访问权限的代码空间, 在JS中, 作用域是在函数中维护的.表示变量或函数起作用的区域,指代了它们在什么样的上下文中执行,亦即上下文执行环境.Javascript的作用域只有两种:全局作用域和本地作用域,本地作用域是按照函数来区分的.