精华内容
下载资源
问答
  • JavaScript 作用域 作用域链作用域作用域链 作用域 作用域就是变量与函数的可访问范围,作用域控制着变量与函数的可见性生命周期。换句话说,作用域决定了代码区块中变量其他资源的可见性。 function fun() { ...
  • 作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域的工作原理。今天这篇文章对JavaScript作用域和作用域作简单的介绍,希望能帮助大家更好的学习JavaScript。任何程序...
  • 虽然对于许多新手开发者来说,作用域的概念并不是很容易理解,本文我会尽我所能用最简单的方式来解释作用域和作用域,希望大家有所收获! 作用域(Scope) 1. 什么是作用域 作用域是在运行时代码中的某些特定部分中...
  • 作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域的工作原理。今天这篇文章对JavaScript作用域和作用域作简单的介绍,希望能帮助大家更好的学习JavaScript。 ...
  • 作用域和作用域在Javascript和很多其它的编程语言中都是一种基础概念。但很多Javascript开发者并不真正理解它们,但这些概念对掌握Javascript至关重要。 正确的去理解这个概念有利于你去写更好,更高效和更简洁的...
  • 主要介绍了js作用域和作用域及预解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 本文主要介绍了JavaScript中作用域和作用域解析,条理分明,方便理解,这里推荐给小伙伴们,有需要的朋友可以参考下
  • 前端面试系列-JavaScript作用域和作用域

    千次阅读 热门讨论 2021-03-22 11:24:09
    前端面试系列-JavaScript作用域和作用域 全局作用域,函数作用域,块级作用域

    当JavaScript代码执行一段可执行代码(executable code)时,会创建对应的执行上下文(execution context)。对于每个执行上下文,都有三个重要属性:

    • 变量对象(Variable object,VO)
    • 作用域链(Scope chain)
    • this

    那么作用域链是什么呢?一起来看看。

    作用域

    作用域,就是变量或者是函数能作用的范围。

    1.全局作用域

    除了函数中定义的变量之外,都是全局作用域。

    var a = 1;
    function bar(){
        console.log(a);
    }
    bar();//1
    

    a就是全局变量,在函数里也可以访问a

    2.函数作用域

    创建函数后在花括号中声明的一些语句或变量只在当前函数中起作用。

    var a = 10;
    function bar(){
       var a  = 20;
        console.log(a);
    }
    console.log(a);//10,取的全局作用域中的a
    bar();//20,取的局部作用域中的a
    

    3.块级作用域

    ES6带来的新特性,在语句块中声明的语句或变量只在当前语句块中起作用。

    函数作用域和块级作用域根本没有直接关系,函数作用域在ES5和ES6作用完全一样,变量不论是使用var声明还是使用了let ,const声明在外部都是不可以访问的。

    块级作用域指的就是使用 if () { }; while ( ) { } …这些语句所形成的语句块 , 并且其中变量必须使用let或const声明(否则就不是块级作用域了),保证了外部不可以访问语句块中的变量。

    if(true) {
    let name='douqing';
    console.log(name); // douqing
    }
    console.log(name); // ReferenceError: name is not defined
    

    经典例子

    for(var i=0;i<4;i++){
        setTimeout(function(){
        	console.log(i);
        },200);
    }
    //4 4 4 4
    

    利用函数形成函数作用域

    for(var i=0;i<4;i++){
        (function(j){
                setTimeout(function(){
        	console.log(j);
        },200);
        })(i)
    }
    //0 1 2 3
    

    利用let形成块级作用域

    for(leti=0;i<4;i++){
        setTimeout(function(){
        	console.log(i);
        },200);
    }
    //0 1 2 3
    

    作用域链

    当查找变量的时候,会先从当前作用域的变量对象中查找,如果没有找到,就会从父级作用域(上层环境)的变量对象中查找,一直找到全局作用域的变量对象,也就是全局对象。这样由多个作用域的变量对象构成的链表就叫做作用域链。它由当前环境与上层环境的一系列变量对象组成,保证了当前执行环境对符合访问权限的变量和函数的有序访问。

    var a = 20;
    function test() {
        var b = a + 10;//当前作用域没有a,往上找,找到a = 20;
        function innerTest() {
            var c = 10;
            return b + c;//当前作用域没有b,往上找,找到b = a+10;
        }
        console.log(d);//Uncaught ReferenceError: d is not defined,一直往上找,最终也没找到d,所以报错
        return innerTest();
    }
    test();//40
    

    本文链接:https://blog.csdn.net/qq_39903567/article/details/115069564

    展开全文
  • 主要和大家一起聊一聊JavaScript作用域和作用域,什么是JavaScript作用域和作用域,感兴趣的小伙伴们可以参考一下
  • 主要介绍了Javascript变量的作用域和作用域详解,本文用一个实例和运行结果来讲解这两个知识,需要的朋友可以参考下
  • 主要介绍了JavaScript高级之词法作用域和作用域,有需要的朋友可以参考一下
  • 作用域和作用域的理解

    千次阅读 2021-07-18 18:55:49
    ES6之前JavaScript没有块级作用域,只有全局作用域和局部作用域。ES6的到来,为我们提供了块级作用域,可通过命令let和const来体现。 所有未定义直接赋值的变量自动声明为全局变量 2. 什么是作用域 如果想得到在...

    作用域(scope)

    1. 什么是作用域

    作用域是在运行代码中某些特定部分中变量、函数和对象的可访问性。也就是说,作用域决定了代码区块中变量和其他的可访问性。
    ES6之前JavaScript没有块级作用域,只有全局作用域和局部作用域。ES6的到来,为我们提供了块级作用域,可通过命令let和const来体现。

    • 所有未定义直接赋值的变量自动声明为全局变量
    2. 什么是作用域链

    如果想得到在当前的作用域里没有定义的变量(即自由变量)的值,需要向父级作用域(下文有解释)寻找,如果父级没有,会接着向上寻找,如果直到在全局作用域里没有找到,就宣布放弃。这种一层层的关系,就是作用域链。

    3. 自由变量取值的理解

    无论fn函数在哪里调用,都要到创建fn这个函数的哪个作用域(即静态作用域)里取值。

    var a = 10
    function fn() {
      var b = 20
      function bar() {
        console.log(a + b)
      }
      return bar
    }
    var x = fn(),
      b = 200
    x() //30
    

    原因是JavaScript是解释型语言,他的执行分为解释和执行两个阶段:

    解释阶段:

    • 词法分析
    • 语法分析
    • 作用域规则确定

    执行阶段:

    • 创建执行上下文
    • 执行函数代码
    • 垃圾回收

    也就是说:

    • 作用域在函数定义的时候就确定的,不会改变。
    • 执行上下文时this的指向是执行时确定的,可随时改变。
    展开全文
  • 作用域和作用域 精解

    千次阅读 2019-05-24 17:24:58
    **作用域(scope):一个变量的可用范围 2种: 全局作用域 :任何地方都可以访问,反复使用 函数作用域(局部作用域):仅在函数内部可访问,不能反复使用 例子: var a=10; function fun() { var a=100;...

    作用域(scope):一个变量的可用范围

    2种:
    全局作用域 :任何地方都可以访问,反复使用

    函数作用域(局部作用域):仅在函数内部可访问,不能反复使用
    例子:

    var a=10;
    	function fun()
    	{
    		var a=100;
    		a++;
    		console.log(a);
    	}
    	fun();//101
    
    	console.log(a);//10
    

    函数的生命周期

    作用域前言
    每个函数都有自己的执行环境,(首先,所有的环境会形成 一个环境栈)。当代码执行进入一个函数后(也就是开始执行函数里的代码了),函数的执行环境会被推进(push)这个大的环境栈中,当函数执行完成后,大的环境栈就会将该函数的环境栈挤出(pop),并将控制权交还给原先的执行环境,就是在回到原来的执行流上去了。

    当代码在执行环境中执行时,变量对象的作用域链就被创建了。作用域链的目的就是为执行环境有权访问的变量和函数提供有序的访问,不让其乱套。有顺序的来。作用域链的前端(或最接近的,最里面的,最里层的)始终都是当前正在执行的代码所在的执行环境的变量对象。

    如果执行环境是函数,则将其活动对象(activation object)简称:AO 作为变量对象。活动对象最开始只包含一个变量,arguments对象(在全局环境中不存在)。这就是该函数的作用域链上最前端的,最里面的了,该作用域链上下一个变量对象就是来自于包含(即外部)环境,再下一个也是来自再下一个外部环境,一层一层的逐渐的往外剥皮,知道最外面的全局环境。全局环境的变量对象就是该作用域链上最后一个对象了。

    注释:’‘函数的作用域链上最前端的,最里面’'指的是预编译将全局对象中的声明和函数(执行函数列表参数,声明变量,函数内部嵌套的函数)提升到最上方,从上至下执行。-----可以百度参考变量提升和函数提升,或js预编译

    1、开始执行前
    1-1 创建执行环境栈(ECS数组):临时保存正在执行的函数的环境
    1-2 向执行环境栈中加入第一个默认函数main()
    1-3.创建全局作用域对象window

    2、定义函数时
    2-1.创建函数对象,封装定义
    2-2. 声明函数名变量,引用函数对象
    2-3. 函数对象的scope属性引用回,创建函数时的作用域

    在这里插入图片描述
    3、调用函数时
    3-1 ESC中加入一个新的元素(执行环境),记录新函数调用
    3-2 创建一个活动对象,保存本次函数调用用到的局部变量
    3-3 ESC新执行环境元素,引用活动对象
    3-4 活动对象中的parent属性引用函数的scope指向的父级作用域对象
    3-5 在执行过程中:优先使用活动对象中的局部变量
    3-6 局部中没有,才延parent向父级作用域找*
    在这里插入图片描述
    ** 4、调用函数后
    4-1 执行环境栈中本次函数的执行环境出栈
    4-2 导致活动对象被释放 导致局部变量一同释放

    在这里插入图片描述

    作用域链

    作用域链*:由多级作用域连续引用形成的链式结果
    掌管一切变量的使用顺序: 先在局部找,没有,就延作用域向父级作用域找

    在JavaScript中,函数也是对象,实际上,JavaScript里一切都是对象。函数对象和其它对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性。其中一个内部属性是[[Scope]],该内部属性包含了函数被创建的作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。

    当一个函数创建后,它实际上保存一个作用域链,并且作用域链会被创建此函数的作用域中可访问的数据对象填充。例如定义下面这样一个函数:

    function func() {
    var num = 1;
    alert(num);
    }
    func();

    在函数func创建时,它的作用域链中会填入一个全局对象,该全局对象包含了所有全局变量,如下图所示(注意:图片只例举了全部变量中的一部分):

    在这里插入图片描述

    执行此函数时会创建一个称为“运行期上下文(execution context)”(有人称为运行环境)的内部对象,运行期上下文定义了函数执行时的环境。每个运行期上下文都有自己的作用域链,用于标识符解析,当运行期上下文被创建时,而它的作用域链初始化为当前运行函数的[[Scope]]所包含的对象。

    这些值按照它们出现在函数中的顺序被复制到运行期上下文的作用域链中。它们共同组成了一个新的对象,叫“活动对象(activation object)”,该对象包含了函数的所有局部变量、命名参数、参数集合以及this,然后此对象会被推入作用域链的前端,当运行期上下文被销毁,活动对象也随之销毁。新的作用域链如下图所示:
    在这里插入图片描述
    外部环境不能访问内部环境的任何变量和函数。即可以向上搜索,但不可以向下搜索。

    可以理解为什么有关于作用域链的定义说,作用域链是一群对象,或者对象列表(链表)。也有总结如下:

    对于javascript最顶层的代码(不包含任何函数定义内的代码),其作用域链只包含一个对象:即全局对象。
    对于不包含嵌套函数的函数,其作用域链包含两个对象:其自身的变量对象和全局变量对象。
    对于包含了嵌套函数的函数,其作用域包含至少三个对象:自身的变量对象,外层的(将自身嵌套的),全局变量对象。

    展开全文
  • 在JavaScript中,变量的作用域有全局作用域和局部作用域两种。  1. 全局作用域(Global Scope)  在代码中任何地方都能访问到的对象拥有全局作用域,一般来说以下几种情形拥有全局作用域:  (1)最外层函数和...

    任何程序设计语言都有作用域的概念,简单的说,作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。在JavaScript中,变量的作用域有全局作用域和局部作用域两种。

      1.  全局作用域(Global Scope)

      在代码中任何地方都能访问到的对象拥有全局作用域,一般来说以下几种情形拥有全局作用域:

      (1)最外层函数和在最外层函数外面定义的变量拥有全局作用域,例如:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    var authorName="山边小溪";

    function doSomething(){

        var blogName="梦想天空";

        function innerSay(){

            alert(blogName);

        }

        innerSay();

    }

    alert(authorName); //山边小溪

    alert(blogName); //脚本错误

    doSomething(); //梦想天空

    innerSay() //脚本错误

      (2)所有末定义直接赋值的变量自动声明为拥有全局作用域,例如:

    1

    2

    3

    4

    5

    6

    7

    8

    function doSomething(){

        var authorName="山边小溪";

        blogName="梦想天空";

        alert(authorName);

    }

    doSomething(); //山边小溪

    alert(blogName); //梦想天空

    alert(authorName); //脚本错误

      变量blogName拥有全局作用域,而authorName在函数外部无法访问到。

      (3)所有window对象的属性拥有全局作用域

      一般情况下,window对象的内置属性都拥有全局作用域,例如window.name、window.location、window.top等等。

      1.  局部作用域(Local Scope)  

      和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部,所有在一些地方也会看到有人把这种作用域称为函数作用域,例如下列代码中的blogName和函数innerSay都只拥有局部作用域。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    function doSomething(){

        var blogName="梦想天空";

        function innerSay(){

            alert(blogName);

        }

        innerSay();

    }

    alert(blogName); //脚本错误

    innerSay(); //脚本错误

    作用域链(Scope Chain)

      在JavaScript中,函数也是对象,实际上,JavaScript里一切都是对象。函数对象和其它对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性。其中一个内部属性是[[Scope]],由ECMA-262标准第三版定义,该内部属性包含了函数被创建的作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。

      当一个函数创建后,它的作用域链会被创建此函数的作用域中可访问的数据对象填充。例如定义下面这样一个函数:

    1

    2

    3

    4

    function add(num1,num2) {

        var sum = num1 + num2;

        return sum;

    }

      在函数add创建时,它的作用域链中会填入一个全局对象,该全局对象包含了所有全局变量,如下图所示(注意:图片只例举了全部变量中的一部分):

     

    JavaScript作用域链

     

      函数add的作用域将会在执行时用到。例如执行如下代码:

    1

    var total = add(5,10);

      执行此函数时会创建一个称为“运行期上下文(execution context)”的内部对象,运行期上下文定义了函数执行时的环境。每个运行期上下文都有自己的作用域链,用于标识符解析,当运行期上下文被创建时,而它的作用域链初始化为当前运行函数的[[Scope]]所包含的对象。

      这些值按照它们出现在函数中的顺序被复制到运行期上下文的作用域链中。它们共同组成了一个新的对象,叫“活动对象(activation object)”,该对象包含了函数的所有局部变量、命名参数、参数集合以及this,然后此对象会被推入作用域链的前端,当运行期上下文被销毁,活动对象也随之销毁。新的作用域链如下图所示:

     

    JavaScript作用域链

     

      在函数执行过程中,没遇到一个变量,都会经历一次标识符解析过程以决定从哪里获取和存储数据。该过程从作用域链头部,也就是从活动对象开始搜索,查找同名的标识符,如果找到了就使用这个标识符对应的变量,如果没找到继续搜索作用域链中的下一个对象,如果搜索完所有对象都未找到,则认为该标识符未定义。函数执行过程中,每个标识符都要经历这样的搜索过程。

    作用域链和代码优化

      从作用域链的结构可以看出,在运行期上下文的作用域链中,标识符所在的位置越深,读写速度就会越慢。如上图所示,因为全局变量总是存在于运行期上下文作用域链的最末端,因此在标识符解析的时候,查找全局变量是最慢的。所以,在编写代码的时候应尽量少使用全局变量,尽可能使用局部变量。一个好的经验法则是:如果一个跨作用域的对象被引用了一次以上,则先把它存储到局部变量里再使用。例如下面的代码:

    1

    2

    3

    4

    5

    function changeColor(){

        document.getElementById("btnChange").onclick=function(){

            document.getElementById("targetCanvas").style.backgroundColor="red";

        };

    }

      这个函数引用了两次全局变量document,查找该变量必须遍历整个作用域链,直到最后在全局对象中才能找到。这段代码可以重写如下:

    1

    2

    3

    4

    5

    6

    function changeColor(){

        var doc=document;

        doc.getElementById("btnChange").onclick=function(){

            doc.getElementById("targetCanvas").style.backgroundColor="red";

        };

    }

      这段代码比较简单,重写后不会显示出巨大的性能提升,但是如果程序中有大量的全局变量被从反复访问,那么重写后的代码性能会有显著改善。

    改变作用域链

      函数每次执行时对应的运行期上下文都是独一无二的,所以多次调用同一个函数就会导致创建多个运行期上下文,当函数执行完毕,执行上下文会被销毁。每一个运行期上下文都和一个作用域链关联。一般情况下,在运行期上下文运行的过程中,其作用域链只会被 with 语句和 catch 语句影响。

      with语句是对象的快捷应用方式,用来避免书写重复代码。例如:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    function initUI(){

        with(document){

            var bd=body,

                links=getElementsByTagName("a"),

                i=0,

                len=links.length;

            while(i < len){

                update(links[i++]);

            }

            getElementById("btnInit").onclick=function(){

                doSomething();

            };

        }

    }

      这里使用width语句来避免多次书写document,看上去更高效,实际上产生了性能问题。

      当代码运行到with语句时,运行期上下文的作用域链临时被改变了。一个新的可变对象被创建,它包含了参数指定的对象的所有属性。这个对象将被推入作用域链的头部,这意味着函数的所有局部变量现在处于第二个作用域链对象中,因此访问代价更高了。如下图所示:

     

    JavaScript作用域链

     

      因此在程序中应避免使用with语句,在这个例子中,只要简单的把document存储在一个局部变量中就可以提升性能。

      另外一个会改变作用域链的是try-catch语句中的catch语句。当try代码块中发生错误时,执行过程会跳转到catch语句,然后把异常对象推入一个可变对象并置于作用域的头部。在catch代码块内部,函数的所有局部变量将会被放在第二个作用域链对象中。示例代码:

    1

    2

    3

    4

    5

    try{

        doSomething();

    }catch(ex){

        alert(ex.message); //作用域链在此处改变

    }

      请注意,一旦catch语句执行完毕,作用域链机会返回到之前的状态。try-catch语句在代码调试和异常处理中非常有用,因此不建议完全避免。你可以通过优化代码来减少catch语句对性能的影响。一个很好的模式是将错误委托给一个函数处理,例如:

    1

    2

    3

    4

    5

    try{

        doSomething();

    }catch(ex){

        handleError(ex); //委托给处理器方法

    }

      优化后的代码,handleError方法是catch子句中唯一执行的代码。该函数接收异常对象作为参数,这样你可以更加灵活和统一的处理错误。由于只执行一条语句,且没有局部变量的访问,作用域链的临时改变就不会影响代码性能了。

    展开全文
  • JS 作用域和作用域

    千次阅读 2018-08-27 16:23:33
    1. 作用域 作用域就是代码的执行环境,全局执行环境就是全局作用域,函数的执行环境就是私有作用域,它们都是栈内存。 执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为。每个执行环境都有一个...
  • 在ES6之前,javascript只有全局作用域和函数作用域。所谓作用域就是一个变量定义并能够被访问到的范围。也就是说如果一个变量定义在全局(window)上,那么在任何地方都能访问到这个变量,如果这个变量定义在函数...
  • js的作用域和作用域的面试题

    千次阅读 2018-08-18 00:01:02
  • js底层原理作用域和作用域

    千次阅读 2019-07-31 22:05:18
    [[scope]]指的是我们所说的作用域作用域链),其中存储了运行期期上下文的集合。每一个函数都有一个作用域。 运行期上下文:当函数执行的过程之前,会创建一个称为执行期上下文的内部对象。一个执行期上下文定义了...
  • 这篇博文是我在心情...JS的变量作用域分为:全局作用域和函数作用域(局部作用域) 在google的控制台里,可以看到 、用var 声明的变量a1是全局变量,是window对象的属性 、用var声明的变量a2和a3,都是loc...
  • 一.跨域问题的解决方法 ...所谓同源是指协议、域名端口都一致的情况。 怎么解决跨域问题: 1.第三方网站开启HTTP的Access-Control-Allow-Origin参数 只有当目标页面的response中,包含了 Ac
  • 深入理解JavaScript中的作用域作用域链和闭包

    万次阅读 多人点赞 2018-05-14 17:00:19
    作用域先来谈谈变量的作用域 变量的作用域无非就是两种:全局变量局部变量。 全局作用域: 最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的:&lt;script&gt; var outerVar...
  • 作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域的工作原理。今天这篇文章对JavaScript作用域和作用域作简单的介绍,希望能帮助大家更好的学习JavaScript。 ...
  • 作用域和作用域及预解析

    千次阅读 2019-04-08 16:29:36
    局部作用域和全局作用域 js中没有块级作用域—一对括号中定义的变量,这个变量可以在大括号外面使用 函数中定义的变量是局部变量 作用域:变量的使用,从里向外,层层的搜索,搜索到了就可以直接使用了 层层搜索,搜索到...
  • js中作用域和作用域的详解,以及常见的一不小心就出做错的小代码片段

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 902,110
精华内容 360,844
关键字:

作用域和作用域链