• javascript进阶系列专题:作用域与作用域链


        字面意思,作用域是指变量和函数的作用范围,换言之,作用域决定了变量和函数的可见性和有效时间。javascript作用域是用函数来区分,与其他语言的大括号不同。

    for (var i=0; i<5; i++){
        var mystring = "平底斜";
        console.log(i); 
    }
    alert(mystring);//弹出"平底斜"

        这段代码在javascript中运行正常,在其他语言中就会报错。这是因为javascript的作用域是基于函数,而不是大括号。

        作用域分为全局作用域和局部作用域。

        有三种情况会出现全局作用域:

        1、最外层定义的变量和函数

    var mystring = "平底斜";
    function fun(){
        alert("Hello World");
    }

        变量mystring和函数fun()拥有全局作用域,在任何位置都可以直接调用。

        2、未定义的变量

    function fun(){
        var   a=b=0;
        mystring = "平底斜";
        console.log(mystring);
    }
    fun();
    alert(b);

        变量mystring没有使用var进行变量声明,所以即使在函数内部也是全局变量。容易忽略的是变量b,看上去使用var进行了声明,实际上只对变量a进行了声明,等同于

    function fun(){
        var a=(b=0); //自右向左赋值
        mystring = "平底斜";
        console.log(mystring);
    }

        一个JS文件中应该尽可能少的出现全局变量,最佳实践是使用var进行变量声明,并且在声明的同时进行赋值。

    function fun(){
        var a=0, b=1, c=2; //等同于var a=0; var b=1; var c=2;
    }
    fun(); alert(c); //脚本报错,因为c是局部变量

        3、全局对象window

    var mystring = "平底斜";
    console.log(mystring); console.log(window.mystring); console.log(window[
    "mystring"]); console.log(this.mystring); console.log(this["mystring"]);//此处this就是window,针对this以后会专题讲解

        全局变量都可以看做window的属性,使用方法就如以上代码:可以用"."也可以用"[]"甚至可以省略window

        局部变量只有一种情况:在函数内部声明的变量拥有局部作用域

    function fun(){
        var mystring="平底斜"; //局部变量
        console.log(mystring);
    }
    fun();
    console.log(mystring); //脚本报错

        冷知识:

        全局变量中,使用var声明与不使用var是有区别的,var声明的变量无法删除,未声明的变量可以删除。

    var mystring="平底斜";
    newstring = "博客园";
    delete mystring;
    delete newstring;
    console.log(mystring);  //"平底斜"
    console.log(newstring); //脚本报错

        作用域链由内向外查找变量,在内部找到变量便停止查找,否则往上一层作用域查找,直到最外层都没有找到变量则返回undefined

    var myscope = "平底斜";
    function fun(){
        var myscope = "博客园";
        console.log(myscope); //"博客园"
    }
    fun();

        上面这段代码,就是因为作用域链有内向外,先在函数内部查找myscope,找到了就直接返回该变量值,并停止查找。

        易错点:

    var myscope = "平底斜";
    function fun(){
        console.log(myscope); //脚本报错
        var myscope = "博客园";
        console.log(myscope); //"博客园"
    }
    fun();

        声明变量会在当前作用域中置顶,又叫变量提升或者声明置顶。以上代码等同于:

    var myscope = "平底斜";
    function fun(){
        var myscope;
        console.log(myscope); //脚本报错
        myscope = "博客园";
        console.log(myscope); //"博客园"
    }
    fun();

        需要注意的是变量提升是在函数定义时发生,并不是在函数调用时:

    var myscope = "平底斜";
    function fun1(){  
        console.log(myscope);
    }
    function fun2(){ 
    var myscope = "博客园";
    fun1();
    }
    fun2(); //"平底斜"

         如上,fun2()调用fun1()时,是先在fun1()中搜索myscope,找不到时再到父级作用域中查找。作用域的嵌套关系是在定义时产生,而不是在调用的时候。

  • 相关阅读:
    Java:线程的六种状态及转化
    Java:多线程概述与创建方式
    小白学Java:RandomAccessFile
    如何用IDEA开启断言
    如何通过IDEA添加serialVersionUID
    小白学Java:I/O流
    更改IDEA相对路径
    小白学Java:File类
    小白学Java:内部类
    Leetcode数组题*3
  • 原文地址:https://www.cnblogs.com/newgold/p/javascript_scope.html
Copyright © 2020-2023  润新知