初识JS作用域

1、首先是作用域的一个概念 :简单地将作用域分为两部分 :

 1)作用  作用即程序的读与写(虽然并不完整 但暂时这样理解)

 2)域       域就是空间 范围 区域

那么在JS中最最常见的两个作用域就是<script></script>和 function(){} 这两者的区别可以看成是  :

1)<script></script>是一个全局的函数  由上到下进行解析(当有很多个<script>作用域时)

2)function(){} 由里向外


2、其次需要有一个浏览器解析的步骤认识(作用域都是先解析后执行的)   浏览器对JS代码的解析是从<script>标签开始的   分为两步:

1)JS预解析(可以看成是一个“仓库”  把解析出来的东西先放进这个“仓库”内)  解析的东西包括:

①var 变量   JS中因为没有明确定义变量时要具体定义成什么变量  所以在浏览器预解析到有变量的时候 先把变量名放入"仓库"  而不去管这个变量是什么类型的变量 全部赋以undefined值

②function函数     在正式运行代码之前  将整个函数块先放入“仓库‘中

③参数  性质和变量一致


那么这里又会出现一个新的问题  预解析的时候如果遇到重名问题  最常见的概括为以下两种情况:

①变量与函数重名时   留下函数(这与函数和变量在代码中出现的先后次序是无关的)这是因为此时的变量是个undefined值  而函数function也是一个类型  比起undefined更具有意义

②函数与函数或者是变量与变量重名时  就遵循后面的覆盖掉前面的函数或变量(先后次序原则)


2)逐行解读代码  在预解析后开始逐行解释代码   这边表达式就可以修改预解析的值(也就是修改"仓库"中的值)

       具体表达式 可以是 = +  -   *  /  %  ++    --   !    ||  &&   参数等等等..........


3、作用域链

如果预解析时子级没有找到相应的声明  会往父级找  直到找到最顶级的作用域  此时子级中对父级变量的表达式影响的就是父级的变量  具体看例子4) 但是反过来父级却不会向子级中去找子级预解析时没有解析到的变量  所以想让父级能够得到子级中的变量的值  具体可以看下述内容“其他”

当然作用域链中经常使用到的是with语句 用来临时改变当前作用域


具体例子分析:

1)"仓库"中的重命名问题

   <script>
        /*重名问题的分析 第一步预解析 发现有变量与函数重名问题那么保留函数
        也有函数与函数重名问题 保留"后出现"的函数 即最后仓库中保留的是函数块function a(){alert(4);}
        下面进行逐步解析*/
        alert(a);   // 发现仓库中有函数块a  所以输出function a(){alert(4);}
        var a = 1;  //发现是个表达式  修改仓库中a的值 由函数块改为变量a = 1;
        alert(a);   //发现仓库中有a = 1 输出1
        function a() {  //逐行解析时函数只是一个声明  只有表达式才可以改变"仓库"中变量值
            alert(2);
        }
        alert(a);  //输出1
        var a = 3;  // 仓库中a的值改为3
        alert(a);   //输出3
        function a() {   //同理
            alert(4);
        }
        alert(a);  //输出3
        a();  //此时a是一个值 而不是函数  所以报错a is not a function
    </script>

2)作用域问题1  输出结果为 undefined    1

    <script>
        /*现在函数fn1是<script>的子级,先进行预解析(注意此时的预解析只是针对全局<script>的)
          预解析的结果是 a = undefined  function fn1(){alert(a); var a = 2;}*/
        var a = 1;     //全局预解析中的a变量变为1
        function fn1() {
            alert(a);   //由下述预解析的结果可以知道输出undefined
            var a = 2;  //函数作用域中的a变量变为2,函数执行结束后由GC回收
        }
        fn1();   // 调用函数,进入函数的作用域,先进行预解析,预解析的结果是a = undefined
        alert(a);  //输出全局预解析中的a 即现在的1
    </script>

3)作用域问题2   输出结果为1   2   1

    <script>
        /*<script>作用域预解析后结果为 a = undefined function fn1(a){...}*/
        var a = 1;
        function fn1(a) {  //此时a是一个参数 参数也是表达式 此时相当于是var a = 1;
            alert(a);  //输出1
            var a = 2;   //表达式改变a的值 a = 2
            alert(a);  //输出2,函数结束GC回收
        }
        fn1(a); /*函数fn1的预解析结果为 a = undefined*/
        alert(a);  //输出<script>域中的a = 1;
    </script>


3)* 多了一个arguments的使用  其实在function中参数a 变量a和arguments[0]是一样的

    <script>
        /*预解析为 a = undefined function fn1(a){...}*/
        var a = 1;  // a = 1;
        function fn1(a) {   // 相当于var a = 1;
            arguments[0] = 3;  //相当于 a = 3;
            alert(a);  //output number 3
            var a = 2;  // a = 2;
            alert(arguments[0]);  //output number 2
        }
        fn1(a);  /*预解析为 a = undefined*/
        alert(a); //output number 1
    </script>




4)作用域链问题

    <script>
        /*<script>作用域的预解析结果为a = undefined   function fn1(){...}*/
        var a = 1;  //改变a的值为a = 1
        function fn1() {
            alert(a);  //在自己的预解析"仓库"中没有找到a 那么就往父级<script>作用域的预解析"仓库"中找,结果
                        //找到了a = 1那么就输出
            a = 2;  //改变父级<script>作用域中a的值 a = 2 注意现在fn1的"仓库"是空的 所以GC没有东西可以回收;
        }
        fn1();  /*预解析时候碰到没有var的变量声明  也没有函数声明  可以看成现在的函数的仓库为空*/
        alert(a);  //输出 a = 2;
    </script>


其他:所以由上一些内容可以知道如果想要获取函数内的值基本上就可以通过两种方式

1)利用作用域链  让父级的变量去获取

    <script>
        var str;
        function fn1() {
            var tmp = 'abc';
            str = tmp;
        }
        fn1();
        alert(str);
    </script>

2)
    <script>
        function fn1() {
            var tmp = 'abc';
            fn2(tmp);
        }
        function fn2(a) {
            alert(a);
        }
        fn1();
    </script>



    

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值