• JavaScript 一、 ES6 声明变量,作用域理解


    // JavaScript
    /*
    * =========================================================
    *
    * 编译原理
    * 尽管通常将 JavaScript 归类为“动态”或“解释执行”语言,但事实上它是一门编译语言。 这个事实对你来说可能显而易见,也可能你闻所未闻,取决于
    * 你接触过多少编程语言,具有多少经验。但与传统的编译语言不同,它不是提前编译的,编译结果也不能在分布式系 统中进行移植。
    *
    * 分词/词法分析(Tokenizing/Lexing)
    * 这个过程会将由字符组成的字符串分解成(对编程语言来说)有意义的代码块,这些代 码块被称为词法单元(token)。
    * 例如,考虑程序var a = 2;。这段程序通常会被分解成 为下面这些词法单元:var、a、=、2 、;。空格是否会被当作词法单元,取决于空格在
    * 这门语言中是否具有意义。
    *
    *
    * 解析/语法分析(Parsing)
    * 这个过程是将词法单元流(数组)转换成一个由元素逐级嵌套所组成的代表了程序语法 结构的树。这个树被称为“抽象语法树”
    * (Abstract Syntax Tree,AST)。 var a = 2; 的抽象语法树中可能会有一个叫作 VariableDeclaration 的顶级节点,接下 来是一个叫作
    * Identifier(它的值是 a)的子节点,以及一个叫作 AssignmentExpression 的子节点。AssignmentExpression 节点有一个叫作
    * NumericLiteral(它的值是 2)的子 节点。
    *
    * 代码生成
    * 将 AST 转换为可执行代码的过程称被称为代码生成。这个过程与语言、目标平台等息 息相关。 抛开具体细节,简单来说就是有某种方法可以
    * 将 var a = 2; 的 AST 转化为一组机器指 令,用来创建一个叫作 a 的变量(包括分配内存等),并将一个值储存在 a 中。
    *
    *
    *
    * JavaScript 三大实现构成
    * 一、ECMAScript:JavaScript的核心
    * 二、DOM(document object model):把整个页面映射为一个多节点的结构,借助DOM提供的API,可以轻松的对节点增加,删除,替换。
    * 三、BOM(browser object model):可以控制浏览器显示的页面以外的东西,如:窗口和框架等。
    *
    * WEB浏览器只是ECMAScript的宿主环境之一,其次还有:Node,Adobe Flash等。
    *
    * JavaScript 中顶层对象
    * 1、window对象,它是JavaScript的最顶层对象,其它的BOM对象都是windows对象的属性;
    * 2、document对象表示浏览器中加载页面的文档对象;
    * 3、location对象包含了浏览器当前的URL信息;
    * 4、navigator对象包含了浏览器本身的信息;
    * 5、screen对象包含了客户端屏幕及渲染能力的信息;
    * 6、history对象包含了浏览器访问网页的历史信息。
    *
    * 变量:声明的变量是存在与栈内存(先进后出),引用存放在堆内存(先进先出),。
    * 1.栈内存:存储变量,包括引用变量,存储在RAM中,是先进后出的,并且像列表一样的由上而下排列,向下则是增加一个变量,向上则是释放一个变量。
    * 2.堆内存:存储对象,存储在RAM中,是先进先出,像集合一样的一个内存池。
    *
    * 作用域:定义存储变量的一套规则,LHS(为变量赋值) 和 RHS(得到某某的值),并在的编译时,编译器和引擎都需要和作用域
    * 一次次的沟通并确认作用域中是否存在此变量。
    *
    * 当一个html文件调用多个js文件时(只有一个窗口),使用var定义变量时:它们都属于同一个作用域,并且window这种顶层对象中时共用的。
    *
    * 当使用LET定义变量时,不会出现在顶层对象(window)中,ES6引入了块的概念,所以let定义的变量时存储在当前块(暂存死区)中,在此块之外的地方
    * 都将不能使用,并且在let之前使用let定义的变量将直接抛出 ReferenceError错误。
    *
    * var定义的变量将出现在顶层对象(window)中,var定义变量时,会有一个变量提升的功效:即的var定义变量之前可以使用,但值却时undefined,因为
    * 在编译的过程中会把变量声明提升到当前作用域的最上方,即:var a = 10; 在编译时,var a; 然后是 a = 10;变量赋值并没有做提升,只是声明被提升了,
    * 这是因为:JavaScript 在语言设计时,易与实现。
    *
    * const定义的值变量,并不能更改其值。当定义引用变量时,其值是可以更换的,但是引用是不能更换,否则都将抛出TypeError
    *
    * *不使用标示符声明变量*
    * 不使用标示符声明变量,类似var声明变量一样,有一个特性不同,在非严格模式下,当在作用域对变量进行RHS(得到某某的值),如果直至全局作用域找不到,
    * 将会抛出ReferenceError,如果在作用域对变量进行LHS(为某某变量赋值),直至全局作用域还找不到变量,全局作用域中就会"创建一个"具有该名称的
    * 全局变量并将其返还给引擎。
    *
    * *严格模式*
    * 与松散模式相比,其中一个不同的行为是严格模式禁止自动或隐式地创建全局变量,LHS查询失败时,会与RHS一样抛出ReferenceError。
    *
    * Error
    * ReferenceError 同作用域判别失败相关,而 TypeError 则代表作用域判别成功了,但是对 结果的操作是非法或不合理的。
    *
    * 函数:定义函数分为两种,1.function a(){}, 2.var a = function(){},前者是'函数声明',后者是'函数表达式'
    * 1.函数声明会有"提升"的功效,函数表达式则"没有提升"的功效。
    * 2.函数声明的"提升"功效,要优先与变量的提升,即:在同一个作用域中,函数声明提升优先级大于变量优先级。
    * 推荐使用1声明函数,在ES6的出现,可以使用 async 定义函数,也是推荐使用这种。
    *
    *
    *
    * =========================================================
    * */

    // let 定义的值不会在javascript顶层出现,只出现在当前作用域中
    let a = 20;
    console.log(this.a,'this.a'); // undefined

    // var 定义的变量会在顶层出现。
    var b = 30;
    console.log(this.b,'this.b'); // 30

    // 定义的值不会在javascript顶层出现,只出现在当前作用域中
    const c = 10;
    console.log(this.c,'this.c'); // undefined

    // c = 50; // 使用const定义值类型变量时,修改值内容,抛出typeError

    const d = {a: 1, b: 2};
    const e = {c: 1};
    // d = e; // 使用const定义引用类型变量时,修改引用地址,抛出typeError
    d.c = 19; // 使用const定义引用类型变量时,可以修改引用对象内容。
    console.log(d, 'd object'); // 验证通过 Object {a: 1, b: 2, c: 19} "d object"


    /*
    * =========================================================
    *
    * JavaScript 作用域嵌套
    * 1.查找变量规则
    * 引擎从当前作用域中开始查找变量,如果找不到,就向上一级继续查找,当抵达最外层的全局作用域时,无论找到还是没找到,查找过程都将停止。
    *
    * 2.作用域链
    * 作用域链查找变量的规则和作用域嵌套查找变量的方式是一样的。
    *
    * =========================================================
    * */

    // 在foo函数中,找不到f变量时,就会向上级查找变量,在全局作用域中查找到f变量。
    // function foo(a) {
    // console.log(a + f,'==a + f');
    // }
    // var f = 2;
    // foo(2);

    // 对f RHS操作,所以会抛出ReferenceError
    // function foo(a) {
    // console.log(a + f, '==a + f');
    // f = a;
    // }
    // foo(2);

    // 非严格模式下,不使用var let const 等声明变量,对l LHS操作,全局作用域中会对l,创建一个l全局变量变量。
    // 使用严格模式可验证这个证明
    function foo(a) {
    // 'use strict';
    l = a;
    console.log(a + l,'a+b');
    }
    foo(2);
    console.log(this.l,'this.l');
  • 相关阅读:
    MVC知识总结(前序)
    MySql 安装
    django【ORM】model字段类型
    gmail注册时“此电话号码无法用于进行验证”
    Python3 re模块正则表达式中的re.S
    django【ORM】 通过外键字段找对应类
    Django【进阶】modelform
    python3-字符编码
    python3-可变和不可变数据类型
    Django【设计】同功能不同实现模式的兼容性
  • 原文地址:https://www.cnblogs.com/zero-zf/p/6815503.html
Copyright © 2020-2023  润新知