作用域、解构、箭头函数

news2024/11/14 23:23:00

作用域

局部作用域

函数作用域(一直 存在)
块作用域(ES6,只有let和const有块级作用域,var没有)

块就是一对大括号,比如{ }、if(){ }、for(…){ }
使用var则失去块级作用域

//例如
for(var i=1;i<=3;i++)
{console.log(i)}
console.log(i);//正确,var定义的i是全局变量

全局作用域

script标签和.js文件的最外层就是所谓的全局作用域,在此声明的变量在函数内部也可访问。
全局作用域声明的变量,任何其他作用域都可访问
注意
1.为window对象动态添加的属性默认是全局的,不推荐!
2.函数中未使用任何关键字声明的变量为全局变量,不推荐!!!
3.尽可能少的声明全局变量,防止全局变量被污染

作用域链

作用域链本质上是底层的变量查找机制
在函数被执行时,会优先查找当前函数作用域中查找变量
如果当前作用域找不到则会依次逐级查找父级作用域直到全局作用域

垃圾回收机制(GC)

JS中内存的分配和回收都是自动完成的。内存在不使用的时候会被垃圾回收器自动回收
但不了解JS的内存管理机制,我们同样非常容易造成内存泄漏(内存无法回收)的情况
不在用到的内存,没有及时释放,就叫做内存泄漏

内存的生命周期

JS环境中分配的内存,一般有如下生命周期
1.内存分配:当我们声明变量、函数、对象的时候,系统会自动为他们分配内存
2.内存使用:即读写内存,也就是使用变量、函数等(函数一调用。临时为函数再分配一小块内存,用于运行函数中的局部变量,函数执行完毕,函数中的局部变量就被释放)
3.内存回收:使用完毕,由垃圾回收自动回收不在使用的内存
4.说明:
a)全局变量一般不会回收(关闭页面回收)
b)一般情况下局部变量的值,不用了会被自动回收掉

垃圾回收算法说明

所谓垃圾回收,核心思想就是如何判断内存是否已经不会再被使用了,如果是,就视为垃圾,释放掉
下面介绍两种常见的垃圾回收算法:引用计数法和标记清除法

引用计数法(算法固定,有缺陷被淘汰)

IE采用的引用计数算法,定义“内存不在使用”的标准很简单,就是看一个对象是否有指向它的引用
算法:
1.跟踪记录每个值被引用的次数
2.如果这个值被引用了一次,那么就记录次数1
3.多次引用会累加
4.如果减少一个引用就减1
5.如果引用次数是0,则释放内存

//声明变量,代码运行的时候,就会分配内存,存储对象的内容
//同时,有一个变量指向这个对象,所以这个对象的引用次数为1
let obj={uname:'zzs',gae:20}
//下面的代码意思是让obj2也指向这个对象,所以这个对象的引用次数为2
let obj2=obj
//下面让obj=null ,也就是说obj不再指向对象了,则这个对象的引用次数减1
obj=null
//下面让obj2=null,也就是说obj2不再指向对象了,则这个对象的引用次数减1
obj2=null
//到这里,对象的引用次数为0,则垃圾回收器会自动回收对象占用的内存

引用计数的问题

function fn(){
let o1={}
let o2={}
//给o1增加属性
o1.a=o2;
o2.a=o1
}
fn()
//相互引用,造成对象(o1、o2)的引用次数始终为1,这两个对象占用的内存始终不会释放
//这样就造成了内存的泄漏
标记清除(主流浏览器都在使用)

现在浏览器通用的大多是基于标记清除算法的某些改进算法,总体的思想都是一致的
核心:
1.标记清除算法将“不在使用的对象”定义为“无法达到的对象
2.就是从根部(在js中就是全局对象)出发定时扫描内存中的对象。凡是能从根部到达的对象,都是还需要使用的
3.那些无法由根部出发触及到的对象标记为不再使用,稍后进行回收

闭包(有了let、const之后应用比较少,应付面试)

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

function outer()
{
	let a=10 //构成闭包的要素之一,外层函数中得有一个变量
	function fn()
	{
	console.log(a) //构成闭包的要素之二,内存函数中使用外层函数的变量
	}
	fn()
}
outer()


//常用闭包写法(防止全局变量经常被修改,闭包函数中的内部变量不受到全局变量的影响)

function outer()
{
	let a=10 //构成闭包的要素之一,外层函数中得有一个变量
	function fn()
	{
	console.log(a) //构成闭包的要素之二,内存函数中使用外层函数的变量
	}
	return fn
}
let xx=outer() // xx=function fn(){console.log(a)}
xx()  //调用xx 相当于调用了fn  //外层函数使用内部函数的变量a



变量提升

//代码运行的时候,会把函数的声明、创建提升到当前作用域的最开头
//代码运行的时候,会把用var声明变量(let和const声明的变量不会提升)的声明过程(没有赋值过程)提升到最开头(在函数之后)
console.log(a)
fn()
var a=10
function  fn(){
console.log(123)
}

在这里插入图片描述

提升的特点

提升的时候,把函数提升到最前面,其次是用var声明的变量
提升只会把var声明的变量提升到当前作用域的最前面

var a=1000
function fn()
{
var a
console.log(a) //undefined
}
fn()
let和const的提升问题

变量的创建分为三步:创建—>声明—>赋值
var会把创建和声明,提升到最开头
let会把创建提升到最开头(let创建的变量,在声明之前使用是不行的)
let如果在创建之后,声明之前使用,就进入了“暂时性死区”。

let a=100
function fn(){
//这里有一个隐式的创建过程,会提升到当前作用域的最开头,否则将会输出a=100,不能使用外层的a,let a叫声明
console.log(a)
let a=20
}
fn()

在这里插入图片描述

    <script>
        var a = 100
        var a  //只有重新赋值会覆盖,声明不会覆盖
        console.log(a) //100
    </script>

    <script>


        console.log(a)  //先把函数a提升,后续Var a提升,只是声明,没有覆盖,则a还是函数
        var a = 10  //只把声明var a提升到前面
        function a() {    //函数提升到最前面
            console.log(1111)
        }
        console.log(a)  //a=10
        var a = 20
        //提升只是把声明提升了,赋值的位置不变
        console.log(a)   //a=20
    </script>

在这里插入图片描述

函数

函数参数

动态参数
function sum(){
//实参不固定的时候,干脆形参直接不写
//这样的普通函数中有一个固定对象叫arguments(不能出现在箭头函数中),是一个伪数组(不能调用数组方法),本质上是一个对象,保存传递进来的实参
let num=0
for(let i=0;i<arguments.length;i++)
{num=num+arguments[i]}
}


//实参有几个不固定
sum(2,3)
sum(2,3,4,5)
sum(4,1,8,2,9)
}
剩余参数
function fn(a,b,...c)
{
//a接收了4,b接收了1,...c接收了剩余所有实参
console.log(a,b,c)
}


fn(4,1,5,6,2)

在这里插入图片描述

展开运算符(类似剩余参数)

1.在构造数组时,能够将其他数组和字符串展开

let arr1=[3,4]
let arr2=[5,6]
let arr=[100,200,...arr1]  //将arr1展开放到数组arr中

在为函数传递参数的时候,能够将其他数组或字符串展开

let arr3=[2,8,6,5,9]
function fn(...a) //形参中的...是剩余参数
{}
fn(...arr3) //相当于fn(2,8,6,5,9)  实参中的...是展开运算发

在构造字面量对象的时候,能够展开其他对象

let obj1={uname:'zs',age:20}
let obj2={sex:'男',height:180}
//运用,加入obj的属性
let obj={id:100,...obj1....obj2,weight:75}
函数参数的默认值
//如果实参未传入参数,则当undefined处理
function fn(a,b=10)
{
}
fn(3,4) //传递两个参数,优先使用我们传递进去的实参,也就是a=3,b=4
fn(6) //传递了一个参数,则a=6,没有给b传递实参,则b使用默认的10

箭头函数

箭头函数是ES6中的新语法,是新的声明函数的方式,其目的是为了简化函数的写法

语法

箭头函数属于表达式函数,因此不存在函数提升
简化写法:
箭头函数只有一个参数时可以省略圆括号()
箭头函数函数体只有一行代码时可以省略花括号{},并自动作为返回值被返回
箭头函数中没有arguments,只能使用…动态获取实参

//写法
// (形参)=>{函数体}
let fn=(a,b)=>{
console。log(12345)
}

let fn=(x)=>{return x*x}
//简写
let fn=x=>x*x
//箭头函数的使用。例如当作其他函数的参数,举例
setTimeout(()=>{},1000)

//特别注意
let fn=()=>{return {uname:'zs,age:20}}
//简写不能写成let fn=()=>{uname:'zs,age:20} 因为无法分清这个大括号{}是函数的大括号还是对象的大括号
//写成
let fn=()=>({uname:'zs,age:20})//额外价格小括号,以免引起歧义 

箭头函数内部没有自己的this,箭头函数中的this,把它当作普通变量,使用的时候按照作用域去查找

document.querySelector('button').addEventListener('click',function(){
console.log(this) //这里的this是事件源button
})
//换成箭头函数
document.querySelector('button').addEventListener('click',()=>{
console.log(this)  //这里的this为普通变量,函数中没有则到全局作用域去查找
})

解构

数组的解构

解构赋值
解:展开
构:结构的意思(在js中有结构的变量是数组和对象)
赋值:把一个值赋值给一个变量
总的来说:就是展开数组或对象,将里面的值取出,赋值给一些变量

//数组的解构
//相当于将几个值赋值给几个变量
let [a,b,c,d]=[1,2,3,4]  //变量和值的数量不对等的时候,按顺序赋值
//另一个写法
let [,a,,b]=['老段''琪琪‘,'小军','小名']
//为了给变量a赋值琪琪。变量b赋值小名,又不想创建多余的变量,则可以用逗号代替
let [a,[b,c,d]]=[1,[3,4,5]]  //前后对应,严格保证顺序


对象的解构(用的超级多)

对象的解构不看顺序和顺序无关,
保证 变量名===对象的键 即可实现解构

let {uname,sex}={uname:'zs',age:20.sex:'男'}
//需要什么变量,写什么变量名即可

let person={
uname:'zs',
age:34,
dog:{dname:'旺财',dage:3},
cat:{cname:'小花',cage:2}}

let {uname,dog:{dname}}=person //前后对应

//举例,在传参的时候直接结构出来
function fn({age}){console.log(age)}
fn(person)
对象解构时为变量定义别名
let age=20;
//不能重复定义同一个名字的变量
let {uname,age:其他的名字}={uname:'zs',age:100}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[C++]C++使用yolov9结合bytetrack实现目标追踪演示

【简介】 在C中实现YOLOv9的目标检测与ByteTrack的多目标追踪是一个相对复杂的过程&#xff0c;涉及到深度学习、计算机视觉和实时数据处理等多个领域。下面我将简单介绍这两个技术&#xff0c;并概述如何在C中实现它们。 YOLOv9&#xff08;You Only Look Once&#xff0c;版…

Linux网络编程—— IO多路复用

Linux网络编程—— IO多路复用 1. I/O 多路复用&#xff08;I/O多路转接&#xff09;1.1 常见的几种I/O模型 2. select3. poll4. epoll :star: 1. I/O 多路复用&#xff08;I/O多路转接&#xff09; I/O 多路复用 使得程序能 同时监听 多个文件描述符&#xff0c;能够提高程序的…

关于数据提交上传服务端的数据类型以及项目打包上线的流程

1 请求头的类型&#xff1a; content-type&#xff1b; 01: application/json 数据以json格式请求&#xff1a;{"key":"value"} 02: application/x-www.form-urlencoded from表单的数据格式 name"zs"&age12 03 mutipart/form-data…

数据结构与算法学习【算法思想之二分法基础】

文章目录 数据结构与算法学习【算法思想之二分查找基础】本文学习目标或巩固的知识点 最基础的二分查找&#x1f7e2;通过题目可知题解结果验证 数据结构与算法学习【算法思想之二分查找基础】 本文学习目标或巩固的知识点 学习二分法类题目 巩固基础的二分法 提前说明&#…

2024.3.1 小项目

1、机械臂 #include <myhead.h> #define SER_IP "192.168.125.32" //服务器端IP #define SER_PORT 8888 //服务器端端口号#define CLI_IP "192.168.68.148" //客户端IP #define CLI_PORT 9999 /…

Linux:线程的概念

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》《C》《Linux》 文章目录 前言一、线程的概念线程代码的简单示例 总结 前言 本文是对于线程概念的知识总结 一、线程的概念 在课本上&#xff0c;线程是比进程更轻量级的一种指向流 或 线程是在…

数据库系统架构与DBMS功能探微:现代信息时代数据管理的关键

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua&#xff0c;在这里我会分享我的知识和经验。&#x…

自动化测试介绍、selenium用法(自动化测试框架+爬虫可用)

文章目录 一、自动化测试1、什么是自动化测试&#xff1f;2、手工测试 vs 自动化测试3、自动化测试常见误区4、自动化测试的优劣5、自动化测试分层6、什么项目适合自动化测试 二、Selenuim1、小例子2、用法3、页面操作获取输入内容模拟点击清空文本元素拖拽frame切换窗口切换/标…

SpringCloud-Docker安装与详解

Docker 是一款强大的容器化平台&#xff0c;通过其轻量级的容器技术&#xff0c;使应用程序的开发、部署和管理变得更加便捷和高效。本文将深入探讨 Docker 的安装过程&#xff0c;并详细解析其基本概念、组件及常用命令&#xff0c;以帮助读者充分理解和熟练使用 Docker。企业…

基于springboot+vue的工厂车间管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

Spring Boot与Netty打造TCP服务端(解决粘包问题)

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 Spring Boot与Netty打造TCP服务端 前言功能目标项目实现maven坐标构建自定义HandlerChannelInitializer实现server实现 前言 在物联网时代&#xff0c;设备之间的通信变得愈发重要。本文将带你踏上一…

微信小程序云开发教程——墨刀原型工具入门(添加批注+其他操作)

引言 作为一个小白&#xff0c;小北要怎么在短时间内快速学会微信小程序原型设计&#xff1f; “时间紧&#xff0c;任务重”&#xff0c;这意味着学习时必须把握微信小程序原型设计中的重点、难点&#xff0c;而非面面俱到。 要在短时间内理解、掌握一个工具的使用&#xf…

程序员的金三银四求职宝典:如何在关键时期脱颖而出

程序员的金三银四求职宝典&#xff1a;如何在关键时期脱颖而出 程序员的金三银四求职宝典&#xff1a;如何在关键时期脱颖而出摘要 面试技巧分享 &#x1f60a;1. 自我介绍 Tips简洁明了 ✨重点突出 &#x1f50d;结合实例 &#x1f310; 2. 技术问题回答 Tips冷静应对 &#x…

重学SpringBoot3-自动配置机制

重学SpringBoot3-自动配置机制 引言Spring Boot 自动配置原理示例&#xff1a;Spring Boot Web 自动配置深入理解总结相关阅读 引言 Spring Boot 的自动配置是其最强大的特性之一&#xff0c;它允许开发者通过最少的配置实现应用程序的快速开发和部署。这一切都得益于 Spring …

扑克牌翻牌记忆小游戏源码

源码由HTMLCSSJS组成&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面 效果预览 下载地址 https://www.qqmu.com/2296.html

LeetCode每日一题之 移动0

前言&#xff1a; 我的每日一题专栏正式开始更新&#xff0c;我会分享关于我在LeetCode上刷题时的经验&#xff0c;将经典题型拿出来详细讲解&#xff0c;来提升自己及大家的算法能力&#xff0c;希望这篇博客对大家有帮助。 题目介绍&#xff1a; 题目链接&#xff1a;. - …

HTML5+CSS3+移动web——列表、表格、表单

系列文章 HTML5CSS3移动web——HTML 基础-CSDN博客https://blog.csdn.net/ymxk2876721452/article/details/136070953?spm1001.2014.3001.5501 目录 一、列表 无序列表 有序列表 定义列表 二、表格 表格结构标签 基本使用 合并单元格 三、表单 input 标签 input 标签占位文…

模版进阶C++

非类型模版 之前我们写的模版都是在不知道模版&#xff08;类&#xff09;中有的变量的类型是什么的时候&#xff0c;我们先用模版参数定义&#xff0c;当类实例化的时候在传参确认 非类型模版&#xff1a;模版参数定义的时候也可以定义整型类型&#xff08;c20之后才支持其…

Topaz DeNoise AI:一键让照片重获清晰 mac/win版

Topaz DeNoise AI是一款革命性的图片降噪软件&#xff0c;它利用先进的人工智能算法&#xff0c;帮助用户轻松去除照片中的噪点&#xff0c;恢复图像的清晰度和细节。无论是专业摄影师还是摄影爱好者&#xff0c;Topaz DeNoise AI都能成为他们处理图片时的得力助手。 Topaz De…

【Matlab】Matlab电话拨号音合成与识别(代码+论文)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…