Javascript高级

JSCORE02

复习

  • 正则表达式 RegExp Regular Expression

    正则表达式 就是利用一套固定的字符, 进行模糊的匹配操作

    正则表达式不是JS语言专属的, JS使用必须利用 正则对象 来进行相应操作

    • 字面量写法: /正则/修饰符

    • 修饰符: i 忽略大小写 g 全局匹配

    • 构造写法: new RegExp('正则', '修饰符')

      • 坑: 在JS中, 字符串里有很多固定的 \* 结构, 例如\n换行, \\ 代表\, 没有特殊含义的则呈现其本身, 例如 \d 实际是 d, 所以需要写 \\d 才能代表正则的 \d

    • 正则查找: 字符串.match(正则)

    • 正则格式验证: 正则.test(字符串)

      • 注意: 正则必须带开头^和结尾$, 代表整个字符串的格式

    • 正则替换: 字符串.replace(正则, 要替换成什么)

      • 捕获组: 利用() 在正则中代表捕获组, 利用 $n 代表第几个捕获组捕捉的值

    • 万能方法: 正则.exec(字符串) 每次调用, 查询1个符合条件的, 需要搭配 do...while 循环才能查询所有.

  • 函数

    • 函数重载: 函数根据参数不同/参数类型不同, 在内部执行不同的逻辑代码

      • 关键知识点: arguments变量, 所有函数本身都自带一个 arguments 变量, 其中存放了函数的所有参数, 是一个类数组类型, 可以通过下标取值: arguments[0] 获取序号0的参数

    • 声明提升: 本质是 JS引擎的预编译机制. JS代码在执行之前, 会先预读一次, 把其中的声明操作 都提前读取

      • var: 预读后, 默认值为 undefined

      • let: 预读后, 处于 暂存死区 状态, 此状态下无法使用, 必须赋值

        • let可变的, 例如亮亮的钱 let money=500

      • const: 预读后, 处于 暂存死区 状态, 此状态下无法使用, 必须赋值

        • const 不可变, 例如 亮亮的老婆 const wife

      • 函数: 会保存整个的函数: 函数名+函数体

    • 作用域: JS共有3种作用域 --

      • 全局作用域(window)

      • 函数作用域(函数的{}范围)

      • 块级作用域 (let 和 {} 结合)

    • 作用域链: 作用域链的本质是 函数声明时会保存其所在的词法环境

      • 函数中使用的变量, 会按照就近原则 使用上层作用域中 最近的

    • 闭包

      • 现象: 函数在执行时, 会保存其声明时所在环境的变量.

      • 作用: 避免全局变量污染

  • window对象

    • JS在浏览器上运行时, 浏览器会提供一个 window 对象, JS默认的各种方法都存储在这个对象中, var 声明的变量也会存储在这个对象中

    • node.js: 没有window对象, 他的全局对象叫: globalThis

闭包

闭包的重要性: 面试几乎必考题, 因为这是JS函数的特殊设定, 属于JS的核心原理.

JS的预编译机制: JS代码执行之前,会把函数整体搬运到外部区域. 此时为了保障函数可以正常执行, 所以函数内部使用的变量, 也必须同步提取到 外部, 并且保存到函数中: scopes

词法环境: 单词 语法 的环境; 函数声明时所在代码区域的 语法 和 单词环境

 

思考:

  1. JS为什么要设计, 让函数声明时保存其所在的词法环境

    为了函数在后续使用时, 其内部的资源都是存在的, 防止报错!

  2. 匿名函数自调用有什么好处, 相较于先声明个函数, 再调用

    匿名函数不需要 声明变量 存储在全局区. 节省内存.

  3. 用途: 规避全局变量污染

  4. 缺点: 闭包会形成独立的作用域, 其中的变量和函数绑定, 函数存在则闭包就一直存在 浪费内存空间, 需要手动把函数改为null 才能释放闭包中的变量

数据类型的差异

数据类型分两大类:

  1. 基础类型:string number boolean null undefined symbol bigint

    这些类型的特点是 : 体积小

    var a = 5

    由于数据本身体积小, 为了增加查询速度, 变量中直接存储数据的

     

  2. 对象类型: 特点体积大

     

普通数据类型的测试: --数值类型

 

对象的赋值为 引用类型, 本质是地址的赋值

 

 

对象的克隆

 

 

原型

构造函数创建的对象中, 存在相同的方法, 如果每次构造 都创建这些相同的方法, 极其消耗内存.

JS官方设计了 原型 变量, 其中存放了 对象的公共方法

问题

如果在构造函数中, 使用 this.属性名 = 函数 的方式为对象类型添加函数. 则每次new操作都需要生成新的函数, 浪费内存!

解决

原型: 一个公共的对象, 属于构造函数的. 构造函数.prototype , 在new操作时, 会自动传递给对象的 __proto__ 属性

共享的函数, 在不同的对象中, 要使用 其所在对象的属性, 必须利用关键词:this 函数的this关键词 代表其执行时所在的对象!

构造函数的 prototype 原型对象:

  • 默认带有属性1: constructor -- 其所在的构造函数

  • 原型 __proto__ 原型对象 是个 {} 也是具有原型的

原型链

对象在调用属性时, 如果自身没有, 则到 其 __proto__ 属性中查找和使用

var a = {}
a.toString()
//实际调用的是 a.__proto__.toString()

 

 

 

 

今日回顾

  • 闭包: 面试10次 问10次

    JS预编译机制, 会把函数的声明提取到外部;

    函数会被整体(函数名+函数体) 都被提取到 预编译区域 为了函数在未来使用时能够正常运行, 所以函数会把其函数体中使用到的变量 一起提取到预编译区域

    保存在函数的 scopes变量中

    闭包: 函数体会形成新的作用域, 与 全局作用域 隔开; 函数1中的函数2, 使用了函数1中变量, 则函数2就会保存函数1, 函数1就是个闭包

    用途: 避免全局变量污染

    缺点: 闭包不会主动释放, 直到其所在的函数 被主动销毁 才会释放. 浪费内存!

  • 构造函数:

    • 搭配 new 关键词使用

    • 作用: 快速创建出 固定结构的对象

  • 原型: 构造函数的prototype, 对象的__proto__

    • 构造函数中的对象的方法, 避免每次new的时候 都创建新的方法, 浪费内存, 所以存储在一个共享的变量中: 函数.prototype; 每次声明对象, 都会把这个prototype属性 赋值给 对象的__proto__

    • 原型链: JS引擎 在读取对象属性时, 如果对象没有 则到其 __proto__ 中查找. 这种机制就叫原型链

  • 函数的this指向: 指向函数运行时所在的对象

posted @ 2021-11-01 19:13  野居青年  阅读(42)  评论(0)    收藏  举报
/*鼠标跟随效果*/ /* 点击爆炸效果*/ /* 鼠标点击求赞文字特效 */