关于Javascript作用域的一些理解

本文深入探讨了作用域的三种类型:全局、局部和块级作用域的特点。解释了变量声明、函数参数、闭包及作用域链的概念,以及如何在JavaScript中正确地管理和使用作用域。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作用域的类型特点
特点:全局作用域,局部作用域,块级作用域
共同特点:如果作用域之间存在包含关系,也就是子可以拿父,父不可以拿子.

1.在不使用var的情况下改变的是全局变量

	var a = 10;
    function fn(){
        a = 20;		//注意这里并不是var = a;
        console.log(a); //20
    }
    fn();
    console.log(a); 	//20

2.使用var进行重新声明,声明的是局部变量,和全局变量没有关系.

	var a = 10;
    function fn(){
        var a = 20;		//注意这里使用var重新声明
        console.log(a); //20
    }
    fn();
    console.log(a); //10

3.当a作为实参传入到函数中.

    var a = 10;
    function fn(a){		//形参就是函数的内部,局部
    	//等同于 var a;
        a = 20;
        console.log(a);	//20
    }
    fn(a);	//注意:这里a作为实参传递进来
    console.log(a);		//10

其实这里理解形参a也是进行声明的函数内部的局部变量,对全局的变量不会产生影响.
4.作用域是单独的,这里是拿不到每一个 i 的

 //假设arr的长度是10
    for(var i = 0;i < arr.length;i++){
        arr[i].onclick = function(){
            console.log(i);	//10
        }
    }

这里涉及到Javascript的异步,因为for循环自动执行,而点击事件没有立即执行,点击事件会停顿,但是for循环没有等点击事件,还在执行,当点击的时候,for循环已经执行结束了,所有这时候只能拿到for循环结束时候的 i 值.

问题?如果想要拿到每个 i ,也就是说必须把每个 i 都要存下来,所以要有一个独立作用
域把每个 i 存下来(现在拿不到).

方法一

 //假设arr的长度是10
 //这里把 var 改为 let
    for(let i = 0;i < arr.length;i++){
        arr[i].onclick = function(){
            console.log(i);
        }
    }

因为当我们写成var的时候for循环是没有块级作用域的,而let是有块级作用域的,这里修改为let可以相当于for循环里面的内容执行了10遍,每一个都是独立的作用域.

方法二

   for(var i = 0;i < arr.length;i++){
        (function(){
            arr[i].onclick = function(){
                console.log(i);
            }
        })(i)
    }

在使用var的时候,可以使用匿名函数,通过把每个 i 传进去也可以拿到每个 i,相当于我们手动的创建独自的作用域,来存储每个 i

5.前面通过块级作用域是为了可以拿到每个 i,但是有时候也需要把前面的数据覆盖

    function fn(){
        var a = 10;
        a++;
        console.log(a);
    }
    fn();//11
    fn();//11

这里我们每次执行函数.都是重新执行函数fn,a都会重新被声明赋值.

问题?当不允许声明全局的变量a,函数执行两次的结果要求为11,12
    function fn(){
        var a = 10;
        return function(){
            a++;
            console.log(a);
        }
    }
    var f = fn();
    f();	//11
    f();	//12

这里通过 fn 函数执行返回一个函数 f,这时候的 a 相当函数 f 就是一个全局的变量,同时 a 也不会被重新声明,不会被覆盖.

6 .函数存在两个作用域

	定义作用域:在哪个位置定义的
	执行作用域:函数在哪执行的
	在函数执行时,可以拿到定义作用域中存在值变量

7.函数变量的读取读取顺序

当前作用域(参数) ->父级作用域->......全局作用域->抛出错误
  var a = 10;
    function fn(a){
        console.log(a); //hello  参数也是在当前作用域中
    }
    fn("hello");
  var a = 10;
    function fn(a){
        a = 20;
        console.log(a);	//20 当前作用域
    }
    fn("hello");
  var a = 10;
    function fn(a){
        console.log(a);	//10 全局作用域
    }
    fn(a);

以上是对作用域的一些理解,可能还不是特别具体,在闭包,以及在严格模式(“use strict”)下的作用域的情况稍后再整理出来.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值