作用域是什么

编译原理

  • 分词/词法分析

    • 这个过程会将由字符组成的字符串分解成(对编程语言来说)有意义的代码块,这些代码块被称为词法单元
  • 解析/语法分析

    • 词法单元流(数组)转换成一个由元素逐级嵌套所组成的代表了程序语法结构的树(抽象语法树AST)
  • 代码生成

    • 将AST转换为可执行代码的过程称被称为代码生成

理解作用域

  • 处理成员

    • 引擎——负责代码编译和执行

    • 编译器——词法-语法-代码生成

    • 作用域——根据名称查找变量的一套规则

  • 引擎查询(代码执行前)

    • 一个赋值操作的LHS(左侧)和RHS(右侧)查询

      var a = 0       LHS-a,RHS-0
      console.log(a)  LHS-无,RHS-log和a
    • 如果查找的目的是对变量进行赋值,就会使用LHS查询

    • 如果查找的目的是获取变量的值,就会使用RHS查询

词法作用域

词法阶段

  • 定义在词法阶段的作用域,由你在写代码时将变量和块作用域写在哪里来决定的,执行时不变,因此该词法作用域属于静态作用域(相对于动态作用域)

  • 无论函数在哪里被调用,也无论它如何被调用,它的词法作用域都只由函数被创建时所处的位置决定

  • 词法作用域是在写代码或者说定义时确定的,而动态作用域是在运行时确定的(javascript的this也是)

  • 词法作用域关注函数在何处声明,而动态作用域关注函数从何处调用

欺骗词法

  • eval——修改词法

  • with——创建词法

  • 性能

    • 处于运行时才确定的eval和with的使用会导致代码运行变慢

    • 引擎无法在编译时对其作用域查找进行优化,因此只能谨慎地认为这样的优化是无效的

函数作用域和块作用域

块作用域

  • with:用with从对象中创建出的作用域仅在with声明中而非外部作用域中有效

  • try/catch:try/catch的catch分句会创建一个块作用域,其中声明的变量仅在catch内部有效(性能糟糕)

  • ps:任何声明在某个作用域内的变量,都将附属于这个作用域

提升

  • js引擎会将"var a = 2"当作两个单独的声明

    • 第一个是编译阶段的任务(var a=undefined)

    • 第二个则是执行阶段的任务(a=2)

作用域闭包

  • 在自身的作用域外被调用并使得作用域和活动对象被保存的现象

  • 无论通过何种手段将内部函数传递到所在的词法作用域以外,它都会持有对原始定义作用域的引用

  • es6中模块文件中的内容会被当作好像包含在作用域闭包中一样来处理

关于this

  • this是在运行时进行绑定的,并不是在编写时绑定,它的上下文取决于函数调用时的各种条件

this全面解析

绑定规则

  • 默认绑定,隐式绑定,显式绑定和new绑定

优先级

  • new绑定 => 显示绑定 => 隐式绑定 => 默认绑定

bind函数

  • 用于改变作用域和传入预定参数(柯里化的一种)

对象

浅拷贝

Object.assign(目标对象,源对象..)

属性描述符

    writable                            // 是否可写
    enumerable                          // 是否可枚举
    configurable                        // 是否可配置
        Object.preventExtensions()      // 不能增加&&不能修改
        Object.seal()                   // 不能增加&&不能修改&&不能配置&&不能删除
        Object.freeze()                 // 不能增加&&不能修改&&不能配置&&不能删除&&不能访问&&不能遍历

    ps:特性值操作只会影响对象的直接属性,不会影响其引用对象的属性

访问描述符

  • 当使用getter和setter时,会忽略对象的value和writable特性

存在性

  • 判断对象中是否存在对应的属性
    ````
    'key' in obj // 方法一

    Object.prototype.hasOwnProperty.call(对象,属性名) // 方法二
    ````

遍历

  • 对象

    • for..in——进行对象遍历的时候,因游览器差异,顺序是不可靠的
  • 数组

    • for..of——通过调用迭代器对象,然后调用迭代器对象的next()方法进行遍历
      // 数组有内置的@@iterator ,因此for..of可以直接应用在数组上
      // 数组的迭代器对象通过"arr[Symbol.iterator]()"进行获取
      // 对象进行for..of操作的变通方法
    
      for (var key of Object.keys(someObject)) {
          console.log(someObject[key]);
      }   

混合对象"类"

  • 类意味着复制

  • 传统的类被实例化时,它的行为会被复制到实例中;类被继承时,行为也会被复制到子类中

  • 多态——在继承链的不同层次名称相同但是功能不同的函数
    • 看起来似乎是从子类引用父类,但是本质上引用的其实是复制的结果
  • JavaScript也有类似的语法,但是和其他语言中的类完全不同;JavaScript 并不会(像类那样)自动创建对象的副本

  • 混入模式(显式/隐式)可以用来模拟类的复制行为,但是通常会产生丑陋并且脆弱的语法,比如显式伪多态(OtherObj.methodName.call(this,...)),这会让代码更加难懂并且难以维护

原型

Prototype

  • 如果原型链父级的属性被设置为只读,则实例对象无法创建屏蔽属性 (通过Object.defineProperty()可以)

  • 如果原型链父级的属性被设为setter属性,则实例对象的赋值和更改操作都会自动延用原型链上的setter属性,体现为
    实例属性本身的赋值或更改无效,除非setter属性方法下存在赋值操作 (通过Object.defineProperty()可以)

原型继承

  • 真正的类继承是会进行对象复制的,但是javascript的继承本质是原型委托,通过原型来进行对象的关联

  • Object.setPrototypeOf(对象,被继承的原型)

行为委托

对象关联·行为委托

  • 行为委托认为对象之间是兄弟关系,互相委托,而不是父类和子类的关系

  • 通过在两个对象之间使用Object.create(对象)来实现行为委托,这种模式只需要两个实体,而且可以互为关联

  • 只需要集中在对象之间的关联关系,可以更好地支持关注分离原则,创建和初始化并不需要合并为一个步骤(相比new 函数)

  • 除了能让代码看起来更简洁,更具扩展性外,还可以简化代码结构

    var Foo = { /* .. */ };         // 父类
    var Bar = Object.create( Foo ); // 继承父类
    Bar.fn=fnA;                     // 书写子类
    var b1 = Object.create( Bar );  // 获取子类实例

内省检测·检查“类”关系

  • 方法1 => A.isPrototypeOf(b)
  • 方法2 => Object.getPrototypeOf(a)===A.prototype
  • 方法3 => a.__proto__=== A.prototype
  • 方法4 => a instansof A

《你不知道的javascript(上)》笔记的更多相关文章

  1. HTML+CSS笔记 CSS笔记集合

    HTML+CSS笔记 表格,超链接,图片,表单 涉及内容:表格,超链接,图片,表单 HTML+CSS笔记 CSS入门 涉及内容:简介,优势,语法说明,代码注释,CSS样式位置,不同样式优先级,选择器, ...

  2. CSS笔记--选择器

    CSS笔记--选择器 mate的使用 <meta charset="UTF-8"> <title>Document</title> <me ...

  3. HTML+CSS笔记 CSS中级 一些小技巧

    水平居中 行内元素的水平居中 </a></li> <li><a href="#">2</a></li> &l ...

  4. HTML+CSS笔记 CSS中级 颜色&长度值

    颜色值 在网页中的颜色设置是非常重要,有字体颜色(color).背景颜色(background-color).边框颜色(border)等,设置颜色的方法也有很多种: 1.英文命令颜色 语法: p{co ...

  5. HTML+CSS笔记 CSS中级 缩写入门

    盒子模型代码简写 回忆盒模型时外边距(margin).内边距(padding)和边框(border)设置上下左右四个方向的边距是按照顺时针方向设置的:上右下左. 语法: margin:10px 15p ...

  6. HTML+CSS笔记 CSS进阶再续

    CSS的布局模型 清楚了CSS 盒模型的基本概念. 盒模型类型, 我们就可以深入探讨网页布局的基本模型了.布局模型与盒模型一样都是 CSS 最基本. 最核心的概念. 但布局模型是建立在盒模型基础之上, ...

  7. HTML+CSS笔记 CSS进阶续集

    元素分类 在CSS中,html中的标签元素大体被分为三种不同的类型:块状元素.内联元素(又叫行内元素)和内联块状元素. 常用的块状元素有: <div>.<p>.<h1&g ...

  8. HTML+CSS笔记 CSS进阶

    文字排版 字体 我们可以使用css样式为网页中的文字设置字体.字号.颜色等样式属性. 语法: body{font-family:"宋体";} 这里注意不要设置不常用的字体,因为如果 ...

  9. HTML+CSS笔记 CSS入门续集

    继承 CSS的某些样式是具有继承性的,那么什么是继承呢?继承是一种规则,它允许样式不仅应用于某个特定html标签元素,而且应用于其后代(标签). 语法: p{color:red;} <p> ...

  10. HTML+CSS笔记 CSS入门

    简介: </span>年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的<span>脚本解释程序</span>,作为ABC语言的一种继承. & ...

随机推荐

  1. Java也疯狂-分享利用ffmpeg做视频转换的工具

    朋友需要经常将视频统一转换为mp4格式,市面上的工具很多,但是转换的体积.自动化程度等都不好,于是花了一个小时给朋友写了个给予ffmpeg的批量转换工具,功能简单但是很实用,也正好给学习Java的同学 ...

  2. 容器监控工具WeaveScope

    最近一段时间整了一些docker容器,弄了一些基于docker的微服务通信,弄好一套服务系统之后,对于服务的性能,基础数据的监控就显的很重要, 不然就是两眼一抹黑了,要不就是维护成本很高,这些都不符合 ...

  3. C#设计模式学习笔记:(13)模板方法模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7837716.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第一个模式--模 ...

  4. JavaScript-迭代器模式

    迭代器模式 顺序访问一个集合 使用者无需知道集合内部结构(封装) jQuery 示例 <!DOCTYPE html> <html> <head> <meta ...

  5. NServiceBus 入门到精通(一)

    什么是NServiceBus?NServiceBus 是一个用于构建企业级 .NET系统的开源通讯框架.它在消息发布/订阅支持.工作流集成和高度可扩展性等方面表现优异,因此是很多分布式系统基础平台的理 ...

  6. Android中实现照片滑动时左右进出的动画的xml代码

    场景 Android中通过ImageSwitcher实现相册滑动查看照片功能(附代码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/det ...

  7. 安装nanomsg

    xftp上传nanomsg安装包 1.解压安装包tar -xvf nanomsg-1.1.0.tar 进入目录cd nanomsg-1.1.0新建安装目录(在nanomsg-1.1.0目录下)mkdi ...

  8. 【Mac电脑新手技巧】苹果电脑如何更换用户头像?

    想给Mac电脑换一个喜欢的用户头像?苹果电脑的用户头像如何更换? 对于很多Mac小白来说,给自己的Mac换一个可心的用户头像很是必要.但是,大多数Mac新手都觉得无从下手!如果你也想给自己的Mac换一 ...

  9. Android开发中按钮的语法

    按钮的主要作用就是触发一个动作,所以会用到监听器. 如何为按钮添加单机事件监听器: 1.匿名内部类作为单机事件监听器 案例: 首先在.xml文件中添加一个按钮一,然后设置其id属性,然后在main里获 ...

  10. ARC 064 F-Rotated Palindromes

    题意 问有多少个长度为 \(N\) 且字符集大小为 \(K\) 的字符串可以通过回文串旋转 (把第一个字符移到最后)若干次得到.\(N,K\le 10^9\) 做法 设\(f_i\)为最小周期为\(i ...