JavaScript进阶 第一天

  • 作用域
  • 函数进阶
  • 解构赋值

一.作用域

  • 局部作用域
  • 全局作用域
  • 作用域链
  • JS垃圾回收机制
  • 闭包
  • 变量提升

1.1 作用域

① 概念:规定了变量能够被访问的“范围”,离开了这个"范围",变量不能被访问

② 分类

  • 局部作用域

      (1)函数作用域:在函数内部声明的变量,只能在函数内部被访问,外部无法直接访问

1.函数内部声明的变量,在函数外部无法被访问

2.函数的参数也是函数内部的局部变量

3.不同函数内部声明的变量无法互相访问

4.函数执行完毕后,函数内部的变量实际被清空了                

      (2)块作用域:在JavaScript中使用{ }包裹起来的代码称为代码块,代码块内部声明的变量外部将【有可能】无法被访问

1.let声明的变量会产生块作用域,var不会产生块作用域

2.const声明的变量会产生块作用域

3.不同代码之间的变量无法相互访问

4.推荐使用let或const

  • 全局作用域

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

② 全局作用域中声明的变量,任何其他作用域都可以被访问

③ 为window对象动态添加的属性默认也是全局的,不推荐

④ 函数中未使用任何关键字声明的变量为全局变量

⑤ 尽可能少声明全局变量,防止全局变量被污染

1.2 作用域链

① 概念:本质是底层的变量查找机制

  • 在函数被执行时,会优先在当前函数作用域中查找变量
  • 如果当前作用域找不到会依次逐级查找父作用域直到全局作用域

总结

1.嵌套关系的作用域串联起来形成了作用域链

2.相同作用域链中按照从小到大的规则查找变量

3.子作用域能够访问父作用域,父级作用域无法访问子级作用域

1.3.垃圾回收机制

① 垃圾回收机制:简称GC, JS 中内存的回收和分配都是自动完成的,内存在不使用的时候会被垃圾回收器自动回收

内存的生命周期

  • 内存分配:当我们声明变量,函数,对象的时候,系统会自动为他们分配内存
  • 内存使用:即读写内存,也就是使用变量,函数
  • 内存回收:使用完毕,由垃圾回收器自动回收不再使用的内存

③ 说明

  • 全局变量一般不会回收(关闭页面回收)
  • 一般情况下,局部变量的值,不用了,会被自动回收掉

内存泄漏:程序中分配的内存由于某种原因,程序未释放或无法释放叫做内存泄漏

⑤ 算法说明

堆和栈的分配说明:

1.栈(操作系统):由操作系统自动分配释放函数的参数值,局部变量等,基本数据类型放到栈里面

2.堆(操作系统):一般由程序员分配释放,如果程序员不释放,由垃圾回收机制回收,一般存放复杂数据类型

两种常见的垃圾回收算法:引用计数法和标记清除法

引用计数:

  • IE浏览器采用的是引用计数法,定义“内存不再使用”,就是看一个对象是否有指向它的引用,如果没有就回收
  • 跟踪记录被引用的次数
  • 如果被引用了依次,就记录一次,多次引用会累加++
  • 如果减少一个引用就减1
  • 如果引用次数是0,就释放内存

致命问题:

嵌套引用(循环引用):如果两个对象下相互引用,垃圾回收器不会进行回收,就会导致内存泄漏,因为引用次数永远不会为0

标记清除法

  • 现代浏览器已经不再使用引用计数算法了,大多是基于标记清除法的某些改进算法
  • 标记清除算法将"不再使用的对象"定义为"无法达到的对象"
  • 就是从根部(在JS中就是全局对象)触发定时扫描内存中的对象,凡是能够从根部到达的对象都是需要使用的
  • 无法从根部触发触及到的对象被标记为不再使用,稍后进行回收

 1.4.闭包

① 概念:一个函数对周围状态的引用捆绑在一起,内层函数中访问到其外层函数的作用域

② 闭包 = 内层函数 + 外层函数的变量

 ③ 闭包的作用:封闭数据,提供操作,外部也可以访问函数内部的变量

 ④ 基本格式:

 ⑤ 闭包的应用:实现数据的私有

function count () {
//  数据私有  i不会被回收, 可能会有内存泄漏的问题let i = 0
function fn () {i++console.log(i)
}return fn
}
const fun = count()
fun() 

 1.5.变量提升(不建议使用)

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

  • 把所有var声明的变量提升到当前作用域的最前面
  • 只提升声明,不提升赋值

相当于:

var num
console.log(num + '件')

② 注意

  • 变量在未声明即被访问时会报语法错误
  • 变量在var声明之前即被访问,变量的值为undefined
  • let/ const 声明的变量不存在变量提升
  • 变量提升出现在相同作用域中
  • 实际开发中推荐先声明再访问变量

二.函数进阶

  • 函数提升
  • 函数参数
  • 箭头函数

2.1 函数提升

  • 函数提升指的是把所有函数声明提升到当前作用域的最前面
  • 只提升函数声明,不提升函数调用
  • 函数表达式不支持提升
  • 函数提升出现在相同作用域中
// 1.会把所有函数声明提升到当前作用域的最前面
// 2.只提升函数声明,不提升函数调用
fn()
function fn() {console.log('函数提升')
}
// 函数表达式不支持将调用写到声明前面

2.2 函数参数

  • 动态参数
  • 剩余参数

动态参数

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

② 代码

 function getSum() {console.log(arguments);let sum = 0for (let i = 0; i < arguments.length; i++) {sum += arguments[i]}console.log(sum)
}
getSum(1,2,3,4,5,6,7,8,9,10)

③ 注意

  • arguments 是一个伪数组,只存在于函数中
  • arguments 的作用是动态获取函数的实参
  • 可以通过for循环依次得到传递过来的实参

剩余参数

① 剩余参数

  • ...是语法符号,置于最末函数形参之前,用于获取多余的实参
  • 借助...获取到的剩余实参,是个真数组

② 代码

function getSum (a, b, ...arr) {console.log(arr)  // 使用的时候不需要使用...
}
getSum(2, 3)
getSum(1, 2, 3, 4, 5)

③ 展开运算符(...):将一个数组进行展开

  • 展开数组,不会修改原数组
const arr1 = [1, 2, 3]
// 展开数组: 不会修改原数组 应用场景:求数组最大值(最小值), 合并数组
// 最大值
console.log(Math.max(...arr1))
console.log(Math.min(...arr1))
console.log(...arr1)
  • 合并数组
const arr1 = [1, 2, 3]
const arr2 = [4, 5]
const arr = [...arr1, ...arr2]

④ 剩余参数和展开运算符的区别

剩余参数:在函数中使用,会得到一个真数组

展开运算符:数组中使用,数组展开

2.3 箭头函数

  • 基本语法
  • 箭头函数参数
  • 箭头函数this

1.基本语法

 ① 目的:引入箭头函数的目的是更加简短的函数写法并且不绑定this,箭头函数的语法比函数表达式更简洁

② 使用场景:箭头函数更适用于那些原本需要匿名函数的地方

③ 写法

(1)原本匿名函数写法

const fn = function () {console.log(123)
}

 (2)箭头函数基本写法

const fn = () => {console.log(123)
}fn()

(3)箭头函数传参数

const fn = (x) => {console.log(x)
}
fn(1)

(4)只有一个参数的可以省略小括号

const fn = x => {console.log(x)
}
fn(1)

(5)只有一行代码,可以省略大括号

const fn = x => console.log(x)
fn(1)

(6)只有一行代码,箭头函数可以省略return

const fn = x => x + x
console.log(fn(1))

(7)箭头函数可以直接返回一个对象

const fn = (uname) => ({ uname: uname })
console.log(fn('hello'))

2.箭头函数参数

  • 普通函数有arguments 动态参数
  • 箭头函数没有 arguments 动态参数,但是有剩余参数 ...args
const getSum = (...arr) => {let sum = 0for (let i = 0; i < arr.length; i++) {sum += arr[i]}return sum
}
console.log(getSum(1,2,3))

3.箭头函数this

① this指向window

console.log(this)

② 普通函数this指向调用者

function fn () {
// this指向调用者console.log(this)
}

③ 对象里面的普通函数的this指向该对象

        const obj = {name: 'andy',sayHi: function () {console.log(this)}}obj.sayHi()

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

⑤ 普通函数箭头函数指向上一层作用域window

        const fn = () => {console.log(this)}fn()

⑥ 对象方法中的箭头函数中的this指向window

        const obj = {uname: 'pink老师',sayHi: () => {console.log(this)  // 指向 window}}obj.sayHi()

⑦ 这里的this指向obj

        const obj = {uname: 'pink老师',sayHi: function () {let i = 10const count = () => {console.log(this) // obj}count()}}obj.sayHi()

注意:DOM事件回调函数为了方便,还是不太推荐使用箭头函数

2.4 解构赋值

  • 数组解构
  • 对象解构

1.数组解构

① 概念:将数组的单元值快速批量赋值给一系列变量的简洁语法

② 基本语法

  • 赋值运算符 = 左侧的[ ] 用于批量声明变量,右侧数组的单元值将被赋值给左侧的变量
  • 变量的顺序对应数组单元值的位置依次进行赋值操作
const arr = [100, 60, 80]
// 数组解构
const [max, min, avg] = arr
console.log(max, min, avg)

 交换两个变量的值

let a = 1
// 必须加分号
let b = 2;
[b, a] = [a, b]

③ 必须加分号的两种情况

(1)立即执行函数

(function() {})();

(2)数组解构

const str = 'pink'
;[1, 2, 3].map(function (item) {console.log(item)
})

③ 数组解构细节

  • 变量多,单元值少,多余的值为undefined
const [a, b, c, d] = [1, 2, 3]
console.log(a, b, c, d)
  • 变量少,单元值多, 多余的参数没有值接
const [a, b] = [1, 2, 3, 4]
  • 利用剩余参数解决
const [a, b, ...c] = [1, 2, 3, 4]
console.log(a, b, c)
  •  防止undefined传递, 可以给默认参数
const [a = 0, b = 0] = []
console.log(a, b)
  •  按需导入,忽略某些返回值
const [a, b, , c] = [1, 2, 3, 4]
console.log(a, b, c)
  • 多维数组
// 多维数组
const arr = [1, 2, [3, 4]]
console.log(arr[0])
console.log(arr[2][0])// 多维数组解构
const [a, b, [c, d]] = [1, 2, [3, 4]]
console.log(a, b, c, d)

2.对象解构

① 对象解构是将对象属性和方法快速批量赋值给一系列变量的简洁语法

② 基本语法

  • 赋值运算符 = 左侧的 {} 用于批量声明变量,右侧对象的属性值将被赋值给左侧的变量
  • 对象属性的值将被赋值给与属性名相同的变量
  • 解构的变量名不要和外面的变量名冲突报错
  • 对象中找不到与变量名一致的属性时变量值为undefined
const obj = {uname: 'pink',age: 18
}const { uname, age } = obj

③ 给新的变量名赋值:可以从一个对象中提取变量并同时修改新的变量名, 新名字在后面

const uname = 'hello'
const { uname: username, age } = obj
console.log(username)

④ 解构数组对象

const pig = [{uname: '佩奇',age: 18
}]
const [{ uname, age }] = pig
console.log(uname)
console.log(age)

⑤ 多级对象解构

        const pig = {name: '佩奇',family: {mother: '妈妈',father: '爸爸',sister: '乔治'},age: 6}const { name, family: { mother, father, sister } } = pigconsole.log(name, mother, father, sister)

⑥ 多级对象数组解构

        const person = [{name: '佩奇',family: {mother: '妈妈',father: '爸爸',sister: '乔治'},age: 6}]const [{ name, family: { mother, father, sister } }] = personconsole.log(name, mother, father, sister)

3.forEach() 方法

① 作用:遍历数组中的每个元素,将元素传递给回调函数

② 场景:遍历数组的每个元素

③ 语法:

被遍历的数组.forEach(function (当前数组元素,当前元素引号) {

     // 函数体

})

const arr = ['red', 'green', 'pink']
arr.forEach(function(item, index) {console.log(item)console.log(index)
})

 ④ 注意

  • 主要用来遍历数组
  • 参数里面当前元素是必须要写的,索引号是可选的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/90082.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

定长内存池设计ConcurrentMemoryPool

原理 还回来的内存用链表串联起来&#xff0c;称为自由链表 内存块自身进行链接&#xff0c;前四个字节存下一个的地址 结构 template<class T> class ObjectPool { public:T* New(){} private:char* _memory nullptr; //方便切割void* _freeList nullptr; };第一步…

探索 C++ 标准库:std::string 库函数用法示例

目录 引言 一、构造函数 1.1 string() 1.2 string (const string& str) 1.3 string (const string& str, size_t pos, size_t len npos) 1.4 string (const char* s) 1.5 string (const char* s, size_t n) 1.6 string (size_t n, char c&#xff09;​ 二、容…

报名小程序PowerActivity配置

https://github.com/zhihuliukanshan/PowerActivity/assets/100545532/9b3e2a3b-f810-4c1f-90d5-9596d99abbd3 导入代码后&#xff0c;需要配置的位置有&#xff1a; 1、miniprogram\setting\setting.js中的CLOUD_ID&#xff1a; module.exports {//### 环境相关 CLOUD_ID: …

如何在iPhone手机上修改手机定位和模拟导航?

如何在iPhone手机上修改手机定位和模拟导航&#xff1f; English 首先&#xff0c;你需要在Mac电脑上下载安装 Location Simulator/定位模拟工具 和 Runner 这两款应用程序。 完成安装后&#xff0c;打开软件&#xff0c;并用USB连接手机设备 修改iPhone手机定位和模拟导航 …

HTTPS安全通信

HTTPS,TLS/SSL Hyper Text Transfer Protocol over Secure Socket Layer,安全的超文本传输协议,网景公式设计了SSL(Secure Sockets Layer)协议用于对Http协议传输的数据进行加密,保证会话过程中的安全性。 使用TCP端口默认为443 TLS:(Transport Layer Security,传输层…

Windows 11 家庭中文版找不到组策略文件gpedit.msc

最近因为调整日期问题需要用到组策略文件gpedit.msc,但是发现找不到文件 在按键盘 winR 打开运行界面输入 gpedit.msc 回车 Windows找不到文件’gpedit.msc’。请确定文件名是否正确后&#xff0c;再试-次。 检查电脑Windows系统版本 是 Windows 11 家庭中文版 果断早网上搜…

Idea 快捷键整理

Idea快捷键和自动代码补全汇总 idea快捷键汇总 Ctrl 快捷键说明Ctrl F在当前文件进行文本查找 &#xff08;必备&#xff09;Ctrl R在当前文件进行文本替换 &#xff08;必备&#xff09;Ctrl Z撤销 &#xff08;必备&#xff09;Ctrl Y删除光标所在行 或 删除选中的行 &am…

应急响应-钓鱼邮件的处理思路溯源及其反制

0x00 钓鱼邮件的危害 1.窃取用户敏感信息&#xff0c;制作虚假网址&#xff0c;诱导用户输入敏感的账户信息后记录 2.携带病毒木马程序&#xff0c;诱导安装&#xff0c;使电脑中病毒木马等 3.挖矿病毒的传输&#xff0c;勒索病毒的传输等等 0x01 有指纹的钓鱼邮件的溯源处理…

Python Opencv实践 - 图像旋转

import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/pomeranian.png", cv.IMREAD_COLOR)#图像旋转 #Opencv中的旋转&#xff0c;首先通过cv.getRotationMatrix2D获得旋转矩阵 #cv.getRotationMatrix2D(center,ang…

Vue 安装开发者工具

1.下载开发者工具&#xff0c;下载地址&#xff1a;http://book.wiyp.top/App/Vue3开发者工具-谷歌/Vue3.crx 2.打开谷歌浏览器&#xff0c;点击扩展&#xff0c;点击管理扩展程序。 3.开启开发者模式&#xff0c;将 Vue3 开发者工具文件拖拽到浏览器中进行安装。 注&#xff…

测试人进阶技能:单元测试报告应用指南

为什么需要单元测试 从产品角度而言&#xff0c;常规的功能测试、系统测试都是站在产品局部或全局功能进行测试&#xff0c;能够很好地与用户的需要相结合&#xff0c;但是缺乏了对产品研发细节&#xff08;特别是代码细节的理解&#xff09;。 从测试人员角度而言&#xff0…

鸿蒙开发学习笔记2——实现页面之间跳转

鸿蒙开发学习笔记2——实现页面之间跳转 问题背景 上篇文章中&#xff0c;介绍了鸿蒙开发如何新建一个项目跑通hello world&#xff0c;本文将介绍在新建的项目中实现页面跳转的功能。 问题分析 ArkTS工程目录结构&#xff08;FA模型&#xff09; 各目录和路径的介绍如下…

【C++】开源:spdlog跨平台日志库配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍spdlog日志库配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下…

Photoshop快捷键大全

Photoshop是一款非常强大的图像处理软件&#xff0c;它提供了许多快捷键&#xff0c;可以帮助用户更快地完成操作。熟练掌握这些快捷键&#xff0c;可以大大提高工作效率&#xff0c;让您更加专注于创作。 Photoshop快捷键汇总&#xff1a; 一、基本操作快捷键 1. 新建文档…

jQuery-表单验证

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>表单验证</title></head><body&g…

TCGA数据下载推荐:R语言easyTCGA包

#使用easyTCGA获取数据 #清空 rm(listls()) gc() # 安装bioconductor上面的R包 options(BioC_mirror"https://mirrors.tuna.tsinghua.edu.cn/bioconductor") if(!require("BiocManager")) install.packages("BiocManager") if(!require("TC…

Spring Boot实现第一次启动时自动初始化数据库流程详解

随着互联网的发展项目中的业务功能越来越复杂&#xff0c;有一些基础服务我们不可避免的会去调用一些第三方的接口或者公司内其他项目中提供的服务&#xff0c;但是远程服务的健壮性和网络稳定性都是不可控因素。 在测试阶段可能没有什么异常情况&#xff0c;但上线后可能会出…

QT:UI控件(按设计师界面导航界面排序)

基础部分 创建新项目&#xff1a;QWidget&#xff0c;QMainWindow&#xff0c;QDialog QMainWindow继承自QWidget&#xff0c;多了菜单栏; QDialog继承自QWidget&#xff0c;多了对话框 QMainWindow 菜单栏和工具栏&#xff1a; Bar: 菜单栏&#xff1a;QMenuBar&#xff0…

UI设计师的主要职责说明(合集)

UI设计师的主要职责说明1 职责&#xff1a; 1、负责公司移动端、PC端产品相关的交互、UI等设计 2、负责公司宣传册、海报、运营物料、banner等设计 3、负责公司品牌相关的视觉设计 3、制定相关设计规范&#xff0c;提高产品的可用性、不断优化产品体验; 4、与PM、运营紧密…

接口测试实战,Jmeter正则提取响应数据-详细整理,一篇打通...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 在测试时&#xf…