当前位置: 首页 > article >正文

Javascript进阶

作用域

局部作用域

局部作用域分为函数作用域和块作用域。

块作用域:

在 JavaScript 中使用 { } 包裹的代码称为代码块,代码块内部声明的变量外部将【有可能】无法被访问。 

全局作用域 

<script> 标签 .js 文件 的【最外层】就是所谓的全局作用域,在此声明的变量在函数内部也可以被访问。
全局作用域中声明的变量,任何其它作用域都可以被访问


作用域链 

作用域链本质上是底层的变量查找机制

        在函数被执行时,会优先查找当前函数作用域中查找变量

        如果当前作用域查找不到则会依次逐级查找父级作用域直到全局作用域        


 JS垃圾回收机制

1. 什么是垃圾回收机制?
垃圾回收机制(Garbage Collection) 简称 GC
JS中内存的分配和回收都是自动完成的,内存在不使用的时候会被垃圾回收器自动回收。
正因为垃圾回收器的存在,许多人认为JS不用太关心内存管理的问题
但如果不了解JS的内存管理机制,我们同样非常容易成内存泄漏(内存无法被回收)的情况
不再用到的内存,没有及时释放,就叫做 内存泄漏
2.内存的生命周期
JS环境中分配的内存, 一般有如下生命周期:
1. 内存分配:当我们声明变量、函数、对象的时候,系统会自动为他们分配内存
2. 内存使用:即读写内存,也就是使用变量、函数等
3. 内存回收:使用完毕,由垃圾回收自动回收不再使用的内存
4. 说明:
        全局变量一般不会回收(关闭页面回收);
        一般情况下局部变量的值, 不用了, 会被自动回收掉
JS垃圾回收机制- 算法说明
堆栈空间分配区别:
1. 栈(操作系统): 由 操作系统自动分配释放 函数的参数值、局部变量等,基本数据类型放到栈里面。
2. 堆(操作系统): 一般由程序员分配释放,若程序员不释放,由 垃圾回收机制 回收。 复杂数据类型 放到堆里面。

引用计数法

IE采用的引用计数算法, 定义“内存不再使用”,就是看一个对象是否有指向它的引用,没有引用了就回收对象 

算法:
1. 跟踪记录被 引用的次数
2. 如果被引用了一次,那么就记录次数1,多次引用会 累加 ++
3. 如果减少一个引用就 减1 --
4. 如果引用次数是 0 ,则释放内存
核心:
1. 标记清除算法将“不再使用的对象”定义为“ 无法达到的对象 ”。
2. 就是从 根部 (在JS中就是全局对象)出发定时扫描内存中的对象。 凡是能从 根部到达 的对象,都是还 需要使用 的。
3. 那些 无法 由根部出发触及到的 对象被标记 为不再使用,稍后进行 回收

标记清除法

根部扫描对象,能查找到的就是使用的,查找不到的就要回收

 

闭包

概念:一个函数对周围状态的引用捆绑在一起,内层函数中访问到其外层函数的作用域
简单理解: 闭包 =  内层函数 + 外层函数的变量
闭包作用: 封闭数据,提供操作,外部也可以访问函数内部的变量


变量提升

        变量提升是 JavaScript 中比较“奇怪”的现象,它允许在变量声明之前即被访问(仅存在于var声明变量 

变量在未声明即被访问时会报语法错误,变量在var声明之前即被访问,变量的值为 undefined

let/const 声明的变量不存在变量提升



函数进阶 

函数参数

1. 动态参数

arguments 是函数内部内置的伪数组变量,它包含了调用函数时传入的所有实参

2. 剩余参数

1. ... 是语法符号,置于最末函数形参之前,用于获取多余的实参

2. 借助 ... 获取的剩余实参,是个真数组 

展开运算符

展开运算符(…),将一个数组进行展开

箭头函数

语法1:基本写法

2. 箭头函数参数

3. 箭头函数 this
箭头函数不会创建自己的this ,它只会从自己的作用域链的上一层沿用this。

解构赋值 

解构赋值是一种快速为变量赋值的简洁语法,本质上仍然是为变量赋值。

数组解构

 数组解构是将数组的单元值快速批量赋值给一系列变量的简洁语法。

变量多 单元值少的情况

变量的数量大于单元值数量时,多余的变量将被赋值为 undefined 

 变量少 单元值多的情况

利用剩余参数解决变量少 单元值多的情况

防止有undefined传递单元值的情况,可以设置默认值

对象解构 

基本语法

1. 赋值运算符 = 左侧的 {} 用于批量声明变量,右侧对象的属性值将被赋值给左侧的变量
2. 对象属性的值将被赋值给与属性名 相同的 变量
3. 注意解构的变量名不要和外面的变量名冲突否则报错
4.对象中找不到与变量名一致的属性时变量值为 undefined

 

2.给新的变量名赋值 

冒号表示“什么值:赋值给谁

2. 数组对象解构

3. 多级对象解构:

遍历数组 forEach 方法(重点)
forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数
主要使用场景: 遍历数组的每个元素

筛选数组 filter 方法(重点)
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素
主要使用场景: 筛选数组符合条件的元素 ,并返回筛选之后元素的新数组

对象

创建对象三种方式

构造函数

构造函数 : 是一种特殊的函数,主要用来初始化对象
使用场景: 常规的 {...} 语法允许创建一个对象。比如我们创建了佩奇的对象,继续创建乔治的对象还需要重新写一
遍,此时可以通过 构造函数 快速创建多个类似的对象

实例成员&静态成员

静态成员:
构造函数的属性和方法被称为静态成员
实例成员:
通过构造函数创建的对象称为实例对象,实例对象中的属性和方法称为实例成员。

内置构造函数

Object

Object 是内置的构造函数,用于创建普通对象。

常用静态方法
作用: Object.keys 静态方法获取对象中所有属性(键)
作用: Object.values 静态方法获取对象中所有属性值
作用: Object. assign 静态方法常用于对象拷贝

Array

1. 数组常见实例方法-核心方法
2. 数组常见方法- 伪数组转换为真数组
静态方法 Array.from()

String

Number

编程思想

面向过程介绍

面向过程 就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依次
调用就可以了

面向对象介绍

面向对象 是把事务分解成为一个个对象,然后由对象之间分工与合作
在面向对象程序开发思想中,每一个对象都是功能中心,具有明确分工。
面向对象编程具有灵活、代码可复用、容易维护和开发的优点,更适合多人合作的大型软件项目。
面向对象的特性:
封装性
继承性
多态性

构造函数 

封装是面向对象思想中比较重要的一部分,js面向对象可以通过构造函数实现的封装。
同样的将变量和函数组合到了一起并能通过 this 实现数据的共享,所不同的是借助构造函数创建出来的实例对象之 间是彼此不影响的

原型

        构造函数通过原型分配的函数是所有对象所 共享的

        JavaScript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象,所以我们也称为原型对象

        这个对象可以挂载函数,对象实例化不会多次创建原型上函数,节约内存

        我们可以把那些不变的方法,直接定义在 prototype 对象上,这样所有对象的实例就可以共享这些方法。
        构造函数和原型对象中的this 都指向 实例化的对象

原型- this指向

构造函数和原型对象中的this 都指向 实例化的对象 

constructor 属性 

每个原型对象里面都有个constructor 属性( constructor 构造函数
作用: 该属性 指向 该原型对象的 构造函数, 简单理解,就是指向我的爸爸,我是有爸爸的孩子

对象原型

        对象都会有一个属性 __proto__ 指向构造函数的 prototype 原型对象,之所以我们对象可以使用构造函数 prototype 原型对象的属性和方法,就是因为对象有 __proto__ 原型的存在

原型继承

继承是面向对象编程的另一个特征,通过继承进一步提升代码封装的程度,JavaScript 中大多是借助原型对象实现继承
的特性。
龙生龙、凤生凤、老鼠的儿子会打洞描述的正是继承的含义
继承与原型链 - JavaScript | MDN (mozilla.org)

原型链.

基于原型对象的继承使得不同构造函数的原型对象关联在一起,并且这种关联的关系是一种链状的结构,我们将原型对 象的链状结构关系称为原型链

原型链-查找规则

当访问一个对象的属性(包括方法)时,首先查找这个 对象自身 有没有该属性。
如果没有就查找它的原型(也就是 __proto__指向的 prototype 原型对象
如果还没有就查找原型对象的原型( Object的原型对象
依此类推一直找到 Object 为止( null
__proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线
可以使用 instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上

深浅拷贝

浅拷贝

首先浅拷贝和深拷贝只针对引用类型
浅拷贝:拷贝的是地址
常见方法:
1. 拷贝对象:Object.assgin() / 展开运算符 {...obj} 拷贝对象
2.拷贝数组:Array.prototype.concat() 或者 [...arr]

深拷贝

 首先浅拷贝和深拷贝只针对引用类型
深拷贝:拷贝的是对象,不是地址
常见方法:
1. 通过递归实现深拷贝
2. lodash/cloneDeep
3. 通过JSON.stringify()

异常处理

throw 抛异常

try /catch 捕获异常

debugger

处理this

改变this

JavaScript 中还允许指定函数中 this 的指向,有 3 个方法可以动态指定普通函数中 this 的指向
call()
apply()
bind()

性能优化

节流

所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数

防抖

防抖(debounce)
        所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间
开发使用场景- 搜索框防抖
        假设输入就可以发送请求,但是不能每次输入都去发送请求,输入比较快发送请求会比较多
        我们设定一个时间,假如300ms, 当输入第一个字符时候,300ms后发送请求,但是在200ms的时候又输入了一个字符,
则需要再等300ms 后发送请求

http://www.kler.cn/a/371817.html

相关文章:

  • 使用和删除数据库
  • 在线教育系统源码开发详解:网校培训平台搭建的核心技术
  • 「Mac畅玩鸿蒙与硬件7」鸿蒙开发环境配置篇7 - 使用命令行工具和本地模拟器管理项目
  • STM32 I2C通信:硬件I2C与软件模拟I2C的区别
  • 以太网交换安全:DHCP Snooping
  • Git 常用命令与开发流程总结
  • golang包导入注意事项
  • 基于SSM+小程序的垃圾分类管理系统(垃圾3)
  • Notion + Python + scholarly = 超强文献管理助手
  • 神经网络的常用layer
  • vue使用prototype
  • 【Java Maven框架】
  • 五个我经常使用的前端开发的库
  • 【机器学习】任务九:卷积神经网络(基于 Cifar-10 数据集的彩色图像识别分类、基于 CNN 的手写数字识别的实验)
  • 基于java的山区环境监督管理系统(源码+定制+开发)环境数据可视化、环境数据监测、 环境保护管理 、污染防治监测系统 大数据分析
  • 【C++】string 类深度解析:探秘字符串操作的核心
  • python如何完成金融领域的数据分析,思路以及常见的做法是什么?
  • 【Django】创建项目、启动及app过程及遇到的问题和解决方案
  • Firefox和Chrome谁的插件生态系统更完善
  • 8年经验之谈 —— 如何使用自动化工具编写测试用例?
  • Java基础(4)——构建字符串(干货)
  • 结合Intel RealSense深度相机和OpenCV来实现语义SLAM系统
  • 开源AI助力医疗革新:OCR系统与知识图谱构建
  • 大厂物联网(IoT)高频面试题及参考答案
  • HTML入门教程7:HTML样式
  • Go 读取xls文件 (shakinm/xlsReader/xls)