作用域

作者: 买个教训_不定期更新 | 来源:发表于2018-03-01 00:31 被阅读0次

本篇内容是基于你不知道的javaScript上卷以及自认为是重点的内容,比较基础,如有不对。欢迎各位大佬指正

关于javaScript的历史我这里就略过了,有兴趣的小伙伴可以去你不知道的javaScript上卷书籍或者pdf或度娘自行观看

ok,进入主题

1=> 作用域

几乎所以的编辑语言最基本的功能之一 —可储存变量持有的值,并且可对值进行访问或修改

(储存,访问,修改等,这种能力,你可以理解为状态 ,状态让程序可突破和扩展,否则,只能做一些简单的任务),

但是,这些变量住在哪里,值在哪里?它们储存在哪里,重点是,怎么找到它们?这些问题说明需要一套设计良好的规则来存储变量。并且之后可以方便的找到这些变量,这套规则被称为作用域

那么问题A是:

            这些变量住在哪里,值在哪里?它们储存在哪里,重点是,怎么找到它们?

            (内存图) 

答:上图基本的回答了问题A抛出的问题。至于引用指向,值类型等问题。后面会另开文章解答,否则会跑偏本题(作用域),内存中的栈堆池也是分大小的哦。

ok,问题A解决,虽然和作用域没什么关系,但至少我知道问题A的答案a!!

这里需要讲到 =》JS的解析过程

编译:预处理,在这一过程中,JS解释器完成对JS代码的预处理,(词法分析、语法分析)

运行:JS是一种解释型语言,所谓解释型是指代码在执行时被解释器一行一行动态编译和执行,而不是执行前完成编译,即边编译边执行,

执行期:JS引擎按着作用域机制来执行,JS的变量和函数作用域是在定义时决定的,而不是执行时才决定的,所以JS解释器只需要通过静态分析就能确定每个变量和函数的作用域,这种作用域称为静态作用域,如执行时才决定的,这种叫做动态作用域

(如不理解JS解释器是什么的同学,送你们- JavaScript运行环境,宿主环境,

链接:https://www.cnblogs.com/sniper007/archive/2011/10/27/2226270.html

链接:http://blog.csdn.net/chenxianru1/article/details/78470101?locationNum=1&fps=1

)

当然了。js的解析过程其实不单单只有这些的,例如性能的优化等,这里只是指出大纲,复合本篇的部分内容

问题B:为什么要讲到解析过程?

答:因为编译时,词法分析中会延伸出词法作用域

2=> 词法作用域 (助你理解闭包和声明提升)

①:故名思意,词法作用域就是定义在词法阶段的作用域,换句话说,就是你在写代码时。把变量或函数或语句块写在哪里来决定的,保存作用域不变(大部分情况是这样。也有欺骗词法作用域的方法,但不再本讲解内。也不建议去了解)(闭包就是基于词法作用域书写代码时所产生的自然结果)

②无论函数在哪里被调用。如何被调用,它的词法作用域都只由函数被声明时所处的位置决定 (闭包的本质=词法作用域和函数当作值传递。)

分析3步

        第一步:先分析参数

        第二步:再分析变量声明

        第三步:分析函数声明

    具体步骤

        0:  函数(变量)在运行的瞬间,会生成个空的 Active Object (活动对象,注意,是个对象)。下简称AO

        1:  函数接收形参参数,添加到AO的属性,并且这个时候值为undefine,即AO.age=undefine

        1.2:接收实参,添加到AO的属性,覆盖之前的undefine 即AO.age=18

        2:  分析变量声明(注意这里。是声明)。如var age;; (若没有变量var age该声明。跳过。找到函数var age该声明)

                如果中AO还没有age属性,则添加AO属性为undefine,即AO.age=undefine

                如果AO上面已经有age属性了,则不作任何修改 还是var age=18

        3:  分析函数声明

                如果有function age(){}把函数赋给AO.age ,覆盖上一步分析的值 既AO.age=function age(){}

function func(age) {

        console.log(age); 函数 function age()  声明提前,函数优先度大于变量

        var age = 25;

        console.log(age); //25

        function age() {}

        console.log(age); //25

    }

    func(18);

记住以上。词法作用域也就没什么神秘

3=>  函数作用域

全局作用域和局部作用域

简单来说。window下,函数A内附属有变量b或函数c,则为局部作用域,函数A之外的,则为全局作用域。对于变量的查找。都是由内向外的,这个比较简单,就不做过多讲解

4=>  块级作用域

对于部分新接触javaScript的朋友来说。他们似乎看到if/switch/while/for/do等。这些含有{}的关键字,例if(){}else{}.for(){},,觉得,咦。这一块一块的。就是块级作用域的。没毛病啊

比较遗憾。在es6之前。javaScript是没有块级作用域的。以上的那些关键字。其实是语句,语句块,例如:条件语句(if/switch),循环语句(while/for/do),强制跳转语句(break/return/throw)等。es6的let关键字,有兴趣的可以去了解下

5=> 作用域嵌套

emmmmm,这个嘛,函数A里面写个函数B。这就是嵌套了,查找也是由内向外的

6=> 声明提升(也叫声明提前,一个意思)

先有鸡?先有蛋?猜对了给你金坷垃

看完前面的一些概念,应该对作用域比较了解了把,简单一句总结:任何声明在某个作用域内的变量,都将附属于这个作用域

例:var a=2;

词法分析再度来袭!

在前面词法作用域说过了。这里我们看,觉得就是一句var a=2,然而,在JS解释器来看,是两个完全不同的,单独的声明

var a=undefined =》词法分析期

a=2 =》执行期,赋值操作

换个例子。

a=2;

var a;

在词法分析期,var a声明会被提升到该作用域的最顶层,赋值或者其他运行逻辑会留在原地

问题来了。如果我写的函数和变量同名,那么谁是最顶层呢?嘿嘿,看看前面的词法作用域例子就知道了

说到声明提升,或许要说说函数和函数表达式的区别:

foo()

function foo(){}=》这个为函数声明 没毛病 也可以执行

foo()

var foo=function bar(){} =》这就是表达式, 变量foo持有函数bar,在声明提示中var foo=undefined,undefined无法调用啊,所以,会报错

相关文章

  • js作用域

    1 - 作用域 1.1 作用域概述 全局作用域 局部作用域(函数作用域) 1.2 全局作用域 1.3 局部作用域 ...

  • 作用域,作用域链

    1 - 作用域 1.1 作用域概述 全局作用域 局部作用域(函数作用域) 1.2 全局作用域 1.3 局部作用域 ...

  • 变量作用域

    变量作用域:静态作用域、动态作用域JS变量作用域:JS使用静态作用域JS没有块级作用域(全局作用域、函数作用域等)...

  • 一网打尽 JavaScript 的作用域

    JavaScript 的作用域包括:模块作用域,函数作用域,块作用域,词法作用域和全局作用域。 全局作用域 在任何...

  • 作用域

    词法作用域,动态作用域,全局作用域,局部作用域,函数作用域,块级作用域,有些地方还能看到隐式作用域和显示作用域。 ...

  • JS的作用域

    JS的作用域: 全局作用域、函数作用域、eval 作用域、块级作用域 全局作用域: 函数作用域: 结果截屏: 说...

  • [ES6]1.1作用域

    作用域 全局作用域(global/window) 函数作用域/局部作用域(function) 块状作用域({}) ...

  • C - 作用域

    C - 作用域 一个 C 变量的作用域可以是: 块作用域 函数作用域 函数原型作用域 或 文件作用域 作用域描述程...

  • JavaScript作用域分类

    JavaScript作用域分类全局作用域局部作用域函数作用域块级作用域catchwithlet 和 const 什...

  • JS基础---05作用域

    JavaScript基础 1 - 作用域 1.1 作用域概述 全局作用域 局部作用域(函数作用域) 1.2 全局作...

网友评论

      本文标题:作用域

      本文链接:https://www.haomeiwen.com/subject/ehnsjxtx.html