js作用域详解

简介: js作用域详解

js对象

众所周知,js的所有数据类型都是一个对象,例如:

var a = 1;
console.log

声明a=1;a属于number类型,但是number类型又是number对象,有着以下方法:

interface Number {
    /**
      * Returns a string representation of an object.
      * @param radix Specifies a radix for converting numeric values to strings. This value is only used for numbers.
      */
    toString(radix?: number): string;
    /**
      * Returns a string representing a number in fixed-point notation.
      * @param fractionDigits Number of digits after the decimal point. Must be in the range 0 - 20, inclusive.
      */
    toFixed(fractionDigits?: number): string;
    /**
      * Returns a string containing a number represented in exponential notation.
      * @param fractionDigits Number of digits after the decimal point. Must be in the range 0 - 20, inclusive.
      */
    toExponential(fractionDigits?: number): string;
    /**
      * Returns a string containing a number represented either in exponential or fixed-point notation with a specified number of digits.
      * @param precision Number of significant digits. Must be in the range 1 - 21, inclusive.
      */
    toPrecision(precision?: number): string;
    /** Returns the primitive value of the specified object. */
    valueOf(): number;
}

更多关于js对象,可查看:https://codeplayer.vip/p/j7sh5

同样,声明一个函数,其实该函数属于window对象的一个方法:

例如,声明一个atest方法:

function atest() {
    console.log(1);
}

通过console控制台,我们可以看到:

image.png

atest其实是一个window对象下的方法对象

var 局部变量作用域

var 声明一个对象,只作用域当前作用域以下。例如:

var a = 'test';
function b() {
    console.log(a);
}
b();

b函数可以成功调用上层作用域变量:

image.png

但是不能被上层作用域调用:

image.png

在顶级作用域下,var 声明变量,等于全局变量,被window对象接管:

<script>
var aaaa='666';
</script>

image.png

定义全局作用域变量

直接定义不借助var,将定义全局变量,成为window对象的属性:

<script>
    var  a1='666';
    a2='777';
    function test() {
        a3='888';
    }
    test();
    console.log(a1,a2,a3);
</script>

image.png

window对象直接赋值

window对象直接赋值方法,等同于不使用var 关键字定义:

<script>
    window.a1='666';
    window.a2='777';
    function test() {
        a3='888';
    }
    test();
    console.log(a1,a2,a3);
</script>

image.png

同理,可以使用window对象,直接赋值一个函数:

<script>
    window.test = function () {
        console.log(666);
    };
    test();
</script>

image.png

变量作用域覆盖问题

通过var 关键字我们知道,当声明一个变量时,该变量可以被当前作用域,以及下层作用域访问

当下层作用域存在同名变量时,下层变量将覆盖上层变量:

<script>
    var a=1;
  function atest() {
      btest();
      function btest() {
          var a=2;
          console.log('btest:'+a);
      }
      console.log("atest:"+a);
  }
  atest();
</script>

image.png

同时,在子作用域声明的方法,只能在当前作用域或者下层作用域调用

闭包函数,闭包作用域

闭包函数,又称匿名函数,例如:

<script>
    (function () {
        var a = 1;
        console.log(a);
    });
    console.log(a);
</script>

该段函数并没有运行,因为它没有被调用:

image.png

在声明函数之后,在后面增加括号即可实现声明后直接运行:

<script>
    (function () {
        var a = 1;
        console.log(a);
    })();
    console.log(a);
</script>

image.png

赋值闭包函数

可通过赋值一个闭包函数,使其可以二次调用:

<script>
    var atest = function () {
        console.log('hello')
    };
    atest();
    atest();
</script>

image.png

闭包函数增加括号并且赋值,变量将等于闭包函数返回的内容:(他将不再是一个函数,成为了一个函数返回值的对象)

<script>
    var atest = function () {
        var a='666';
        console.log('hello');
        return a;
    }();
    console.log(atest);
</script>

image.png

闭包返回对象

可return一个json型对象,用于调用:

<script>
    var atest = function () {
        var a=1;
        return{
            a:2,
            b:3,
            c:function () {
                //返回上层闭包声明的a变量
                return a;
            }
        };
    }();
    console.log(atest.c());
    console.log(atest.a);//输出闭包return的json对象属性
    console.log(atest.b);
</script>

image.png

在闭包函数中声明的变量,只能在闭包函数内的作用域,以及下层作用域使用,可通过return 对象中,通过return对象中声明的方法进行返回,使得上级作用域能成功访问到闭包作用域的变量

return作用域变量访问情况


在return作用域中的变量,外部可使用        匿名函数赋值的变量.变量名  方式访问,并且改值是引用型的,内部可使用  this.变量名方式

<script>
    var atest = function () {
        return{
            a:2,
            b:1,
            getA:function () {
                //返回上层闭包声明的a变量
                return this.a;
            },
            getB:function () {
                //返回上层闭包声明的a变量
                return this.b;
            }
        };
    }();
    console.log(atest.getA());
    console.log(atest.getB());
    atest.a=7;
    atest.b=6;
    console.log(atest.getA());
    console.log(atest.getB());
</script>

image.png

总结

1:js万物皆对象,所有变量都是对象类型。

2:js的作用域是往下通用的,下层作用域可访问上层作用域的变量,并可修改值

3:js下层作用域变量和上层同名冲突时,下层作用域将覆盖上层变量,但上层作用域的访问不受影响

4:不适用var方法定义的变量,都属于全局变量,也就是window对象的属性

5:可通过window.方法定义全局变量

6:在顶层作用域声明的函数,其实就是window对象的方法

7:闭包在首次声明时,需要加括号自动调用,否则不能调用

8:闭包函数可通过赋值方法调用

9:闭包函数加括号 赋值到变量中,该变量将等于闭包的返回值

10:闭包返回值可返回一个对象,后期可使用  闭包赋值变量名.对象属性方法进行访问

11:闭包函数类var 的变量,只能在闭包函数下层或当前层使用,外部无法访问,但可以通过return 对象中,声明一个方法进行访问

12:闭包函数return的对象,都可以被  外部通过闭包赋值变量名.对象属性 应用,而对象本身也可以通过this.变量名,方式应用

目录
相关文章
|
1月前
|
JavaScript 前端开发
js的作用域作用域链
【10月更文挑战第29天】理解JavaScript的作用域和作用域链对于正确理解变量的访问和生命周期、避免变量命名冲突以及编写高质量的JavaScript代码都具有重要意义。在实际开发中,需要合理地利用作用域和作用域链来组织代码结构,提高代码的可读性和可维护性。
|
1月前
|
自然语言处理 JavaScript 前端开发
[JS]作用域的“生产者”——词法作用域
本文介绍了JavaScript中的作用域模型与作用域,包括词法作用域和动态作用域的区别,以及全局作用域、函数作用域和块级作用域的特点。通过具体示例详细解析了变量提升、块级作用域中的暂时性死区等问题,并探讨了如何在循环中使用`var`和`let`的不同效果。最后,介绍了两种可以“欺骗”词法作用域的方法:`eval(str)`和`with(obj)`。文章结合了多位博主的总结,帮助读者更快速、便捷地掌握这些知识点。
33 2
[JS]作用域的“生产者”——词法作用域
|
4月前
|
JavaScript 前端开发
浅谈js作用域
浅谈js作用域
34 0
|
1月前
|
前端开发 JavaScript 数据处理
CSS 变量的作用域和 JavaScript 变量的作用域有什么不同?
【10月更文挑战第28天】CSS变量和JavaScript变量虽然都有各自的作用域概念,但由于它们所属的语言和应用场景不同,其作用域的定义、范围、覆盖规则以及与其他语言特性的交互方式等方面都存在明显的差异。理解这些差异有助于更好地在Web开发中分别运用它们来实现预期的页面效果和功能逻辑。
|
1月前
|
JavaScript 前端开发
如何在 JavaScript 中实现块级作用域?
【10月更文挑战第29天】通过使用 `let`、`const` 关键字、立即执行函数表达式以及模块模式等方法,可以在JavaScript中有效地实现块级作用域,更好地控制变量的生命周期和访问权限,提高代码的可维护性和可读性。
|
1月前
|
JavaScript 前端开发
javascript的作用域
【10月更文挑战第19天javascript的作用域
|
2月前
|
JavaScript 前端开发
JavaScript 作用域
JavaScript 作用域是指程序中可访问的变量、对象和函数的集合。它分为函数作用域和局部作用域。函数作用域内的变量仅在函数内部可见,而全局作用域的变量在整个网页中均可访问。局部变量在函数执行完毕后会被销毁,而全局变量则在整个脚本生命周期中都存在。未使用 `var` 关键字声明的变量默认为全局变量。
|
2月前
|
JavaScript 前端开发
js作用域
js作用域
17 1
|
3月前
|
JavaScript 前端开发
js 变量作用域与解构赋值| 22
js 变量作用域与解构赋值| 22
|
3月前
|
JavaScript 前端开发
JavaScript基础知识-作用域(action scope)
关于JavaScript基础知识中作用域的介绍。
43 1
JavaScript基础知识-作用域(action scope)