JavaScript高级复习下(60th)

news/2024/5/1 9:00:08/文章来源:https://blog.csdn.net/weixin_55608297/article/details/128025188

1、函数内 this 的指向

在这里插入图片描述

2、严格模式

1、什么是严格模式

JavaScript 除了提供正常模式外,还提供了 严格模式(strict mode)。ES5 的严格模式是采用具有限制性 JavaScript 变体的一种方式,即在严格的条件下运行 JS 代码。

严格模式在 IE10 以上版本的浏览器中才会被支持,旧版本浏览器中会被忽略。

严格模式对正常的 JavaScript 语义做了一些更改:

1、消除了 Javascript 语法的一些不合理、不严谨之处,减少了一些怪异行为。
2、消除代码运行的一些不安全之处,保证代码运行的安全。
3、提高编译器效率,增加运行速度。
4、禁用了在 ECMAScript 的未来版本中可能会定义的一些语法,为未来新版本的 Javascript 做好铺垫。比如一些保留字如:class, enum, export, extends, import, super 不能做变量名

2、开启严格模式

严格模式可以应用到整个脚本或个别函数中。因此在使用时,我们可以将严格模式分为为脚本开启严格模式为函数开启严格模式两种情况。

2.1 为脚本开启严格模式

为整个脚本文件开启严格模式,需要在所有语句之前放一个特定语句:在所有语句之前放一个特定语句 "use strict"

<script>'use strict';console.log('严格模式已开启');
<script/>

有的 script 基本是严格模式,有的 script 脚本是正常模式,这样不利于文件合并,所以可以将整个脚本文件放在一个立即执行的匿名函数之中。这样独立创建一个作用域而不影响其他 script 脚本文件。

<script>(function (){"use strict";var num = 10;})();
</script>

2.2 为函数开启严格模式

要给某个函数开启严格模式,需要把 "use strict";声明放在函数体所有语句之前。

"use strict" 放在函数体的第一行,则整个函数以 “严格模式” 运行。

function fn(){"use strict";return "这是严格模式。";
}
function foo() {console.log("这不是严格模式");
}

3、 严格模式中的变化

3.1 变量规定

1、在正常模式中,如果一个变量没有声明就赋值,默认是全局变量。严格模式禁止这种用法,变量都必须先用 var (let、const)命令声明,然后再使用。

2、严禁删除已经声明变量。例如:delete x; 语法是错误的。

3.2 严格模式下 this 指向问题

1、以前在全局作用域函数中的 this 指向 window 对象。
2、严格模式下全局作用域中函数中的 this 是 undefined。
3、以前构造函数时不加 new 也可以调用,当普通函数,this 指向全局对象
4、严格模式下,如果构造函数不加 new 调用, this 指向的是 undefined 如果给他赋值则会报错
5、new 实例化的构造函数指向创建的对象实例。
6、定时器 this 还是指向 window。
7、事件、对象还是指向调用者。

3.3 函数变化

1、函数不能有重名的参数。

2、函数必须声明在顶层。新版本的 JavaScript 会引入 “块级作用域”( ES6 中已引入)。为了与新版本接轨,不允许在非函数的代码块内声明函数比如if或者for语句

3、垃圾回收机制

Javascript 具有自动垃圾回收机制(GC:Garbage Collecation),也就是说,执行环境会负责管理代码执行过程中使用的内存

原理:垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存

通常情况下有两种实现方式:

1、标记清除
2、引用计数

1、标记清除

JavaScript最常用的垃圾收回机制

1、当变量进入执行环境是,就标记这个变量为“进入环境“。进入环境的变量所占用的内存就不能释放,当变量离开环境时,则将其标记为“离开环境“

2、垃圾回收程序运行的时候,会标记内存中存储的所有变量。然后,它会将所有在上下文(理解为作用域)中的变量,以及被在上下文中的变量引用的变量的标记去掉

3、剩下有标记的变量就是待删除的了,原因是任何在上下文中的变量都访问不到它们了

4、随后垃圾回收程序做一次内存清理,销毁带标记的所有值并收回它们的内存

2、引用计数

语言引擎有一张**“引用表”**,保存了内存里面所有的资源(通常是各种值)的引用次数。如果一个值的引用次数是0,就表示这个值不再用到了,因此可以将这块内存释放

如果一个值不再需要了,引用数却不为0,垃圾回收机制无法释放这块内存,从而导致内存泄漏
比如:

const arr = [1, 2, 3, 4];
console.log('hello world');

上面代码中,数组[1, 2, 3, 4]是一个值,会占用内存。变量arr是仅有的对这个值的引用,因此引用次数为1。尽管后面的代码没有用到arr,它还是会持续占用内存

如果需要这块内存被垃圾回收机制释放,只需要设置如下:

arr = null

通过设置arr为null,就解除了对数组[1,2,3,4]的引用,引用次数变为 0,就被垃圾回收了

3、总结

有了垃圾回收机制,不代表不用关注内存泄露。那些很占空间的值,一旦不再用到,需要检查是否还存在对它们的引用。如果是的话,就必须手动解除引用

4、闭包

1、变量作用域

变量根据作用域的不同分为两种:全局变量和局部变量。

1、函数内部可以使用全局变量。
2、函数外部不可以使用局部变量。
3、当函数执行完毕,本作用域内的局部变量会销毁。

2、闭包的概念

闭包(closure)指有权访问另一个函数作用域中变量的函数。

简单理解就是一个函数和对其周围状态的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)

function init() {var name = "Mozilla"; // name 是一个被 init 创建的局部变量function displayName() { // displayName() 是内部函数,一个闭包alert(name); // 使用了父函数中声明的变量}displayName();
}
init();

displayName() 没有自己的局部变量。然而,由于闭包的特性,它可以访问到外部函数的变量

3、闭包的作用

如何在 fn1() 函数外面访问 fn1() 中的局部变量 x ?

function fn1() {let x = 10;// fn2 是一个闭包function fn2() {console.log(x);}return fn2;
}
let f = fn1();   //f也是一个函数,正常调用就行
f(); // 10

闭包作用:延伸变量的作用范围。

4、闭包应用-点击li输出当前索引号

// 有以下节点:
<ol><li>Banana</li><li>Apple</li><li>Peach</li>
</ol>

错误示例:

for (var i = 0; i < lis.length; i++) {lis[i].onclick = function () {console.log(i); // function是一个异步任务,点击之后才会执行,但是for循环是同步任务,立马去执行,一直输出最后索引+1的索引号}
}

方案1:设置 index 属性

for (var i = 0; i < lis.length; i++) {
lis[i].index = i; //动态添加属性lis[i].onclick = function () {console.log(this.index);}
}

方案2:闭包

立即执行函数也称为小闭包,因为立即执行函数里面的任何一个函数都可以使用它的i变量

for (var i = 0; i < lis.length; i++) {//利用for循环创建了4个立即执行函数(function (i) {    //接受参数// 每一个点击事件的函数成为一个闭包,点击事件内部访问到了来自立即执行函数的变量 ilis[i].onclick = function () {console.log(i); //这个函数里面用到的值是立即执行函数传过来的,形成闭包}})(i); //传递参数
}

5、闭包应用-3s后打印所有li内容(延时调用)

for (var i = 0; i < lis.length; i++) {(function (i) {setTimeout(function () {console.log(lis[i].innerHTML);}, 3000);})(i);
}

5、递归

1、什么是递归

如果一个函数在内部可以调用其本身,那么这个函数就是递归函数。
简单理解:函数内部自己调用自己, 这个函数就是递归函数。
递归函数的作用和循环效果一样。

由于递归很容易发生 “栈溢出” 错误(stack overflow),所以必须要加退出条件 return。

2、利用递归求阶乘

<body><script>function fn(n) {if (n == 0 || n == 1) {return 1;} else {return n * fn(n - 1);}}console.log(fn(8));</script>
</body>

2、递归求斐波那契数列

<body><script>function fb(n) {if (n == 0 || n == 1) {return 1;} else {return fb(n - 1) + fb(n - 2);}}console.log(fb(10));</script>
</body>

6、深浅拷贝

1、浅拷贝

1、浅拷贝,指的是创建新的数据,这个数据有着原始数据属性值的一份精确拷贝

2、如果属性是基本类型,拷贝的就是基本类型的值。如果属性是引用类型,拷贝的就是内存地址

3、即浅拷贝是拷贝一层,深层次的引用类型则共享内存地址

4、下面简单实现一个浅拷贝

<body><script>function shallowCopy(obj) {const newObj = {};//prop是属性名for (let prop in obj) {//hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)。if (obj.hasOwnProperty(prop)) {    //newObj[prop] = obj[prop];}}return newObj}var obj = {id: '1',name: 'andy'};console.log(shallowCopy(obj));</script>
</body>
Object.assign(newObj,obj)  //语法糖

2、深拷贝

深拷贝开辟一个新的栈,两个对象属完成相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性

<body><script>let arr = [5, 4, 9, 8];let obj1 = {name: 'xxx',sex: '男',like: ['红色', '蓝色'],book: {title: 'js程序',price: '88'}};//手写深拷贝function deepClone(obj) {// 查看要拷贝的是数组还是对象,如果数组创建空数组,是对象创建空对象const newObj = obj instanceof Array ? [] : {};for (let k in obj) {//K属性名  obj[k]值//判断当前每个元素是否是对象或者数组 //如果还是对象,继续递归拷贝//是值,直接添加到新创建的对象或者数组里if (typeof obj[k] === 'object') {//实现一个递归拷贝newObj[k] = deepClone(obj[k])} else {    //否则是值, 直接添加到新建的 newObj中newObj[k] = obj[k];}}   return newObj;}console.log(deepClone(obj1));</script>
</body>

方法二:使用JSON字符串实现深拷贝

  // JSON.stringify 简单粗暴var origin_data = { a: 1, b: 2, c: [1, 2, 3] }var copy_data = JSON.parse(JSON.stringify(origin_data))console.log(copy_data)

7、正则表达式

1、什么是正则表达式

正则表达式是一种用来匹配字符串的强有力的武器

它的设计思想是用一种描述性的语言定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的

在 JavaScript中,正则表达式也是对象,构建正则表达式有两种方式:

1、字面量创建,其由包含在斜杠之间的模式组成

var regexp = /表达式/;

2、通过调用 RegExp 对象的构造函数创建

var regexp = new RegExp(/表达式/); 

2、测试正则表达式 test

test() 正则对象方法,用于检测字符串是否符合该规则,该对象会返回 true 或 false,其参数是测试字符串。

regexObj.test(str);

1、regexObj 是写的正则表达式
2、str 我们要测试的文本
3、检测 str 文本是否符合我们写的正则表达式规范

3、正则表达式中的特殊字符

3.1 正则表达式的组成

一个正则表达式可以 由简单的字符构成,比如 /abc/,也可以是 简单和特殊字符的组合,比如 /ab*c/ 。其中特殊字符也被称为元字符,在正则表达式中是具有特殊意义的专用符号,如 ^ 、$ 、+ 等。

3.2 边界符

正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符。
在这里插入图片描述
如果 ^$ 在一起,表示必须是精确匹配(不能多不能少,只能是这些)。

let regexp = /^he$/;
console.log(regexp.test('hello')); // flase
console.log(regexp.test('he')); // true

3.3 字符类

字符类表示有一系列字符可供选择,只要匹配其中一个就可以了。所有可供选择的字符都放在方括号内。

1 [] 方括号

/[abc]/.test('andy')
// true 

正则含义:后面的字符串只要包含 abc 中任意一个字符,都返回 true。

2 [ - ] 方括号内部 - 范围符

/^[a-z]$/.test('c')
// true 

含义:方括号内部加上 - 表示范围,这里表示 a 到 z 26个英文字母都可以。

3 [^] 方括号内部 取反符 ^

/[^abc]/.test('andy')
// false

方括号内部加上 ^ 表示 取反,只要包含方括号内的字符,都返回 false 。

4 字符组合

/[a-z1-9]/.test('andy')
// true

方括号内部可以使用字符组合,这里表示包含 a 到 z 的 26 个英文字母和 1 到 9 的数字都可以。

3.4 量词符

量词符用来设定某个模式出现的次数。
在这里插入图片描述

3.5 括号总结

1、大括号:量词符。里面表示重复次数。
2、中括号:字符集合。匹配方括号中的任意字符。
3、小括号:表示优先级。

3.6 预定义类

在这里插入图片描述

3.7 正则案例

1、手机号码:/^1[3|4|5|7|8][0-9]{9}$/
2、QQ:[1-9][0-9]{4,}(腾讯QQ号从10000开始)
3、昵称是中文:^[\u4e00-\u9fa5]{2,8}$

4. 正则表达式中的替换

1、replace 替换

replace() 方法可以实现替换字符串操作,用来替换的参数可以是一个字符串或是一个正则表达式。

stringObject.replace(regexp/substr,replacement)

1、第一个参数:被替换的字符串 或者 正则表达式
2、第二个参数:替换为的字符串
3、返回值:一个替换完毕的新字符串

2、正则表达式参数

当 replace 中第一个参数为正则表达式的时候,还有一个 switch 参数可选。

/表达式/[switch]

switch(也称为修饰符)按照什么样的模式来匹配. 有三种值:

1、g:全局匹配
2、i:忽略大小写
3、gi:全局匹配 + 忽略大小写

举例:

let msg = 'what\'s the fuck? Damn it!';
msg = msg.replace(/fuck|damn/gi, '****');
console.log(msg); 
// what's the ****? **** it!

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

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

相关文章

【面试宝典】Java八股文之Redis面试题

Redis面试题1、什么是 Redis?2、Redis 与其他 key-value 存储有什么不同?3、Redis 的数据类型?4、使用 Redis 有哪些好处?5、Redis 相比 Memcached 有哪些优势?6、Memcache 与 Redis 的区别都有哪些?7、Redis 是单进程单线程的?8、一个字符串类型的值能存储最大容量是多…

信创产业多点开花,AntDB数据库积极参与行业标准研制,协同价值链伙伴共促新发展

11月&#xff0c;AntDB数据库积极参与多项数据库行业标准研讨会&#xff0c;助推行业规范建立&#xff1b;凭借领先的技术研发能力与企业创新能力&#xff0c;在今年9月入选了《2022爱分析数据智能厂商全景报告》&#xff0c;此次又凭借在信创市场的深入推广&#xff0c;入选《…

【LeetCode每日一题:809.情感丰富的文字~~~双指针+计数器】

题目描述 有时候人们会用重复写一些字母来表示额外的感受&#xff0c;比如 “hello” -> “heeellooo”, “hi” -> “hiii”。我们将相邻字母都相同的一串字符定义为相同字母组&#xff0c;例如&#xff1a;“h”, “eee”, “ll”, “ooo”。 对于一个给定的字符串 S…

101个CV模型集体开源,魔搭社区视觉AI深度解析

作者&#xff1a;谢宣松 达摩院开放视觉智能团队 11月3日&#xff0c;在2022云栖大会上&#xff0c;阿里达摩院联手 CCF 开源发展委员会共同推出了 AI 模型社区“魔搭”ModelScope&#xff0c;旨在降低 AI 的应用门槛。 AI 模型较为复杂&#xff0c;尤其是要应用于行业场景&…

sklearn.metrics模块重要API总结(持续更新)

目录前言各类指标分类指标&#xff08;Classification metrics&#xff09;sklearn.metrics.accuracy_scoresklearn.metrics.aucaverage_precision_score (AP)回归指标&#xff08;Regression metrics&#xff09;多标签排序指标&#xff08;Multilabel ranking metrics&#x…

天宇优配|北上广深角逐“国字号”数据交易所 行业爆点

今日&#xff0c;上海数据生意地点揭牌一周年之际&#xff0c;将发动数据生意节&#xff0c;并将探究树立数交所国际板。10天前&#xff0c;深圳数据生意所正式揭牌。至此&#xff0c;北上广深四个一线城市均已树立数据生意所。 数据作为新型生产要素&#xff0c;正成为各地争相…

Linux登陆配置虚拟机

启用虚拟机一、启动虚拟机1、登录虚拟机2、查看IP地址3、能否PING通外网二、配置静态IP地址1、修改网卡配置文件2、重启网络服务3、重启虚拟机4、查看修改后的IP地址5、测试虚拟机能否Ping通外网三、测试宿主机与虚拟机能否相互Ping通1、测试宿主机能否Ping通虚拟机2、测试虚拟…

云原生系列 六【轻松入门容器基础操作】

✅作者简介&#xff1a; CSDN内容合伙人&#xff0c;全栈领域新星创作者&#xff0c;阿里云专家博主&#xff0c;华为云享专家博主&#xff0c;掘金后端评审团成员 &#x1f495;前言&#xff1a; 最近云原生领域热火朝天&#xff0c;那么云原生是什么&#xff1f;何为云原生&a…

户外运动耳机如何选择、最优秀的五款户外运动耳机推荐

有些人花时间在户外纯粹是为了听听大自然的声音。其他人可能不想在没有娱乐或鼓舞人心的音频选择的情况下跑步、徒步、散步或骑自行车。找到适合锻炼的耳机相当简单&#xff0c;就像健身耳机一样&#xff0c;您会希望这些耳机能够舒适、安全地贴合您的耳朵&#xff0c;这样它们…

m基于PTS+TR的OFDM系统PAPR联合抑制算法matlab仿真

目录 1.算法描述 2.仿真效果预览 3.MATLAB部分代码预览 4.完整MATLAB程序 1.算法描述 部分传输序列(Partial Transmit Sequence , PTS)由于其不受载波数量限制&#xff0c;并且能够有效的&#xff0c;无失真的降低OFDM信号峰均比&#xff0c;而受到广泛关注。部分传输序列算…

docker容器网络

第七章容器网络 Docker网络 veth pair&#xff1a;成对出现的一种虚拟网络设备&#xff0c;数据从一端进&#xff0c;从另一端出。用于解决网络命名空间之间隔离。 docker0&#xff1a;网桥是一个二层网络设备&#xff0c;通过网桥可以将Linux支持的不同端口连接起来&…

开源让这位 00 后逆袭成为各类大奖收割者

OpenI 启智社区在 2022 年推出的开源打榜活动&#xff0c;聚集了一帮非常活跃的开发者&#xff0c;上榜者覆盖了来自全国高校、科研机构、企业达 100 多家。其中&#xff0c;高校学生占 65%&#xff0c;近 60%的上榜者是 90 后&#xff0c;32%的上榜者是 00 后。真是 00 后浪推…

41、集合

一、基本介绍&#xff1a; 1、引入&#xff1a; &#xff08;1&#xff09;前面我们保存多个数据使用的是数组&#xff0c;但数组不足的地方有&#xff1a; 1&#xff09;长度开始时必须指定&#xff0c;而且一旦指定&#xff0c;不能更改 2&#xff09;保存的必须为同一类…

Socket网络编程

参考博客&#xff1a;https://blog.csdn.net/shuux666/article/details/124023652 1、环境查看 通过cmd窗口的命令:ipconfig查看本机IP地址 查看网络情况是否正常:ping百度官网 2、Socket概述 3、套接字建立连接过程 4、Socket网络编程 基本的Socket编程&#xff1a; 本实…

异常(Exception)

随着面向对象的结束&#xff0c;我们的JavaSE也就接近了尾声&#xff0c;还有两个章节没有去梳理&#xff0c;常用类和异常&#xff0c;本章先讲异常&#xff0c;剩下的常用类后面再来补。 废话不多说&#xff0c;直接开始本章的内容。 1. 认识异常 引出&#xff1a; 假设 n…

ArcGIS综合制图教程,简单上手!

目的 1、了解专题地图组成的各个要素&#xff1b; 2、掌握ArcGIS编辑专题图的方法和步骤&#xff1b; 实习内容 使用ArcGIS生成1&#xff1a;200万比例尺的浙江省县级行政区划图&#xff0c;并输出成像文件。 实习步骤 一、将ArcGIS切换到Layout视图&#xff0c;并调整页面…

[附源码]java毕业设计疫情期间物资分派管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

C++初阶(stack+queue)

stack是一种容器适配器&#xff0c;专门用在具有后进先出 (last-in first-out)操作的上下文环境中&#xff0c;其删除只能从容器的一端进行元素的插入与提取操作。stack是作为容器适配器被实现的&#xff0c;容器适配器即是对特定类封装作为其底层的容器&#xff0c;并提供一组…

精华推荐 | 【深入浅出RocketMQ原理及实战】「性能原理挖掘系列」透彻剖析贯穿RocketMQ的系统服务底层原理以及高性能存储设计挖掘深入

设计背景 消息中间件的本身定义来考虑&#xff0c;应该尽量减少对于外部第三方中间件的依赖。一般来说依赖的外部系统越多&#xff0c;也会使得本身的设计越复杂&#xff0c;采用文件系统作为消息存储的方式。 RocketMQ存储机制 消息中间件的存储一般都是利用磁盘&#xff0…

餐饮+KTV融合消费模式,会受消费者喜欢吗?

这个五一&#xff0c;我们雨科网门店系统的客户&#xff0c;大侠火锅店终于是将KTV搬到了自己的门店里&#xff0c;运用门店小程序功能及纸质代金券及礼品的噱头吸引客户进店&#xff0c;只需消费并和任意一人合唱一首歌即可领取&#xff0c;消费者在等餐或放松的时候一键点歌演…