2024蓝旭暑期第二次前端培训课

lznzl 2024-07-11 15:33:03 阅读 52

一、web storage

1.1 什么是 web storage?

Web Storage即浏览器本地存储,是一种在客户端存储数据的技术,它允许网页在用户的浏览器中存储键值对数据。这种存储方式是相对于传统的Cookie存储方式而言的,提供了更多的存储空间和更好的性能。

Web Storage 主要包括两种类型:LocalStorageSessionStorage。  

1.2 localStorage - 本地存储

定义:LocalStorage 是 Web Storage 的一部分,它提供了一种方式来存储页面会话之外的数据。即使浏览器窗口关闭,数据依然存在,直到主动删除。

特点

数据没有时间限制。存储容量较大(通常为 5MB)。数据以键值对的形式存储。同源策略(协议、域名、端口均相同)下,只能访问相同域名下的页面存储的数据。适用于存储主题偏好、用户设置等不需要频繁变动的数据。

1.3 sessionStorage - 会话存储

定义:SessionStorage 也是 Web Storage 的一部分,它与 LocalStorage 类似,但是存储的数据仅在页面会话期间有效。

它是将数据保存在session对象中,所谓session是指用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间。session对象可以用来保存在这段时间内所要求保存的任何数据。当用户关闭浏览器窗口后,存储的数据会被清除。

特点

数据仅在会话期间有效。存储容量同样较大(通常为 5MB)。数据以键值对的形式存储。同源策略下,只能访问相同域名下的页面存储的数据。适用于存储表单数据、用户会话信息等临时性数据

1.4 基本操作

setItem(key, value):设置键值对数据。

getItem(key):根据键名获取对应的值。

removeItem(key):根据键名删除对应的数据。

clear():清除所有存储的数据。 

<code>// 使用 LocalStorage 设置和获取数据

localStorage.setItem('username', 'bluemsun');

console.log(localStorage.getItem('username')); // 输出: bluemsun

// 使用 SessionStorage 设置和获取数据

sessionStorage.setItem('content', '123123');

console.log(sessionStorage.getItem('content')); // 输出: 123123

// 删除数据

localStorage.removeItem('username');

sessionStorage.removeItem('content');

// 清除所有数据

localStorage.clear();

sessionStorage.clear();

二、正则表达式

2.1 什么是正则表达式?

正则表达式(Regular Expression,简称Regex)是一种强大的文本处理工具,用于搜索、替换或解析字符串。在JavaScript中,正则表达式被广泛用于字符串操作。

2.2 创建正则表达式

 两种方式:字面量,构造内置函数(两种方式完全等效)

<script>

//1.字面量的形式

const reg = /abc/

//2.内置构造函数的形式

const reg1 = new RegExp('abc')

console.log(reg) // /abc/

console.log(reg1) // /abc/

</script>

2.3 方法

2.3.1 RegExp方法

①test:在字符串中测试是否匹配

语法: 正则.test(字符串)

符合—>true不符合—>false

②exec:在字符串中执行查找匹配

语法: 正则.exec(字符串) 

 返回一个数组(未匹配到则返回 null)

function demo() {

var regexp1 = /a/;

var str = 'abc'

alert(regexp1.test(str)) // true

alert(regexp1.exec(str)) // a

}

demo()

 2.3.2 String方法

 语法: 字符串.String方法(正则) 

方法 含义
match 一个在字符串中执行查找匹配的 String 方法,它返回一个数组,在未匹配到时会返回 null
matchAll 一个在字符串中执行查找所有匹配的 String 方法,它返回一个迭代器(iterator)
search 一个在字符串中测试匹配的 String 方法,它返回匹配到的位置索引,或者在失败时返回 -1
replace 一个在字符串中执行查找匹配的 String 方法,并且使用替换字符串替换掉匹配到的子字符串
split 一个使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中的 String 方法

2.4 常见规则

2.4.1 常见元字符
元字符 含义
. 匹配任意单个字符(除了换行符)
^ 匹配输入字符串的开始位置
$ 匹配输入字符串的结束位置
* 匹配前面的子表达式0次或多次
+ 匹配前面的子表达式1次或多次
?

匹配前面的子表达式0次或1次

tip:如果紧跟在任何量词 *、 +、? 或 {} 的后面,将会使量词变为懒惰模式(匹配尽量少的字符),和缺省使用的贪婪模式(匹配尽可能多的字符)正好相反

{n} 匹配确定的n次
{n,} 至少匹配n次
{n,m} 最少匹配n次且最多m次
2.4.2 特殊集合
元字符 含义
\d 匹配数字,等同于[0-9]
\w 匹配字母、数字及下划线
\s 匹配任何空白字符,包括空格、制表符、换行符等
\D 匹配非数字
\W 匹配非字母、数字及下划线
\S 匹配非空白字符
2.4.3 特殊字符转义

在正则表达式中,一些字符具有特殊含义,如果你想匹配这些特殊字符本身,需要使用反斜杠 \ 进行转义。(例如\.匹配“.”)

2.4.4 量词

量词可以指定一个模式应该被匹配的次数。

元字符 含义
* 0次或多次
+ 1次或多次
? 0次或1次
{n} 确定的n次
{n,} 至少n次
{n,m} 最少n次且最多m次
2.4.5 断言

断言用于指定一个必须满足的条件,但并不消耗字符。

元字符 含义
\b 匹配单词边界
\B 匹配非单词边界
x(?=y) 匹配'x'仅仅当'x'后面跟着'y'.这种叫做先行断言
(?<=y)x 匹配'x'仅当'x'前面是'y'.这种叫做后行断言
x(?!y) 仅仅当'x'后面不跟着'y'时匹配'x',这被称为正向否定查找
(?<!y)x 仅仅当'x'前面不是'y'时匹配'x',这被称为反向否定查找
2.4.6 组

 组是用来将多个字符或子模式组织在一起的一种方式,它们可以应用量词或其他操作。组分为两种:捕获组和非捕获组。

字符 含义
(x) 匹配 'x' 并且记住匹配项,这种方法叫作捕获组
(?:x) 匹配 'x' 但是不记住匹配项,这种方法叫作非捕获组,使得你能够定义与正则表达式运算符一起使用的子表达式
2.4.7 字符组

使用 [] 可以定义一个字符组,匹配括号内的任意一个字符。(如[abc]:匹配"a"、"b"或"c")

字符 含义
[a-z] 一个字符集合,匹配方括号中的任意字符,包括转义序列,可以使用破折号(-)来指定一个字符范围。
[^a-z] 一个反向字符集。也就是说, 它匹配任何没有包含在方括号中的字符。你可以使用破折号(-)来指定一个字符范围。
2.4.8 选择

使用 | 可以定义多个选择,匹配多个模式中的任意一个。(如(abc|def):匹配"abc"或"def")

2.4.9 高级搜索

 正则表达式有六个可选参数 (flags) 允许全局和不分大小写搜索等。这些参数既可以单独使用也能以任意顺序一起使用,并且被包含在正则表达式实例中。

标志 含义
g 全局搜索
i 不区分大小写搜索
m 多行搜索
s 允许.匹配换行符
u 使用 unicode 码的模式进行匹配
y 执行“粘性(sticky)”搜索,匹配从目标字符串的当前位置开始

语法:

var re = /pattern/flags;var re = new RegExp("pattern", "flags");

三、闭包

 3.1 什么是闭包?

闭包(closure)是一个函数以及其捆绑的周边环境状态(lexical environment,词法环境)的引用的组合。换而言之,闭包让开发者可以从内部函数访问外部函数的作用域,同时保证外层函数无法操作内层函数的变量。在 JavaScript 中,闭包会随着函数的创建而被同时创建。

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

<script>

function outer(){

let a=10;

function fn(){

console.log(a);

}

fn();

}

outer();

</script>

通常会在使用一个函数包裹住闭包结构,以起到对变量的保护作用。

 闭包的常见用法就是提供间接访问一个变量的方法,有时候我们需要在某些地方用到一个变量,但是又不能定义为全局变量,存在着篡改的风险,那么我们就可以用定义位私有变量,然后通过闭包暴露出去。

 3.2 闭包中的return

是否必须用return? =>   no!

什么时候用到return?:外部如果想使用闭包的变量,则需要return

<script>

function outer(){

let a=10

return function(){

console.log(a)

}

}

const fn=outer()

fn()

</script>

3.3 闭包内存泄漏现象

内层函数引用外层函数变量,内层函数占用内存。如果不释放内存,过多时,易引起内存泄露。

function fn(){

let count=1

function fun(){

count++

console.log(`函数被调用了${i}次`)

}

return fun

}

const result=fn()

result()

谁会存在内存泄露?=> count变量

①result是一个全局变量,代码执行完毕不会立即销毁

②result使用fn函数

③fn用到fun函数

④fun函数里面用到count

⑤count被引用就不会被回收,所以一直都存在

此时:闭包引起了内存泄漏

四、立即执行函数

4.1 什么是立即执行函数

立即执行函数(IIFE)是一个在定义时就会立即执行的 JavaScript 函数。就是将匿名函数函数声明转化成函数表达式,再在函数后加()让其立即执行。

//匿名函数

function() {

console.log('这是匿名函数');

}

//函数声明

function test() {

console.log('这是函数声明');

}

//函数表达式:把一个函数声明式赋值给一个变量的形式

var fun = function() {

console.log('这是函数表达式');

};

4.2 立即执行函数的书写格式

当一个函数需要立即执行的情况,该函数必须形成表达式形式

我们在函数声明前面加上“+”、“-”、“!”、“~”和用括号括起来等等,都可以将函数声明形成表达式

以下为两种常用方式

1.W3C推荐的立即执行函数规范是用括号将函数声明和执行符号包起来

(function() {}());

 2.另一种方式

(function() {})();

注意:为保险起见,可以在立即执行函数前面加分号!

 在前面加上分号是为了避免代码编译错误。很多时候我们写js代码都是不写分号的,而js引擎在解析代码时会自动加上。但是如果括号多了,在编译时分辨不出哪些是一组,所以需要手动加上分号。由于很多开发者语句后面不打分号,为了避免,就约定俗成的在立即执行函数前面加上分号

;(function (a){

console.log(a)

})(1);

;(function (a){

console.log(a)

}(2));

 4.3 立即执行函数的优点

可以创建一个与外界没有任何关联的作用域(独立作用域),不会让这个作用域中的变量和方法污染到全局如果想在此私有作用域中使用全局对象,将全局对象以参数形式传入进去即可。执行完成以后自动销毁向外部抛出一系列属性和方法

立即执行函数符合闭包的定义:即使在创建它的上下文之外执行,它也能够访问并保留创建时的词法作用域中的变量。

五、this

this——执行环境上下文对象

无论函数属于谁,从哪来,判断this指向的唯一依据是此刻函数的执行由哪个对象调用 

 1.全局作用域或函数作用域:在全局或一般函数作用域中调用函数时,this指向全局对象(在浏览器中是window,在Node.js中是global)

// 全局作用域

console.log("全局下的this:"+this);

console.log("window:"+window);

console.log(window==this);

// 函数作用域

function outerFunction() {

// 这是一个嵌套的函数,它不是对象的方法

function innerFunction() {

console.log('Inside innerFunction:', this);

}

// 调用嵌套的函数

innerFunction();

}

// 调用外部函数

outerFunction();

2.方法调用:当一个函数作为一个对象的方法被调用时,this指向该对象。

const person = {

name: 'bluemsun',

sayName: function () {

console.log(this.name);

}

};

person.sayName(); // bluemsun

 3.构造函数:在构造函数中,this指向新创建的对象实例(new)。

function Person(name) {

this.name = name;

}

const person1 = new Person('aaa');

console.log(person1.name); // aaa

4.事件处理:在事件处理函数中,this指向绑定事件的元素。

document.getElementById('clickMe').addEventListener('click', function () {

console.log(this); // <button id="clickMe">Click me</button>code>

});

5.箭头函数:箭头函数不绑定自己的this,它会捕获其所在上下文的this值,作为自己的this值。(它只会从自己的作用域链的上一层继承this)

const person2 = {

name: 'bluemsun',

sayName: () => {

console.log(this.name);

}

};

person2.sayName(); // 箭头函数中的this指向全局对象,这里没有name属性

6.显式绑定:可以使用call、apply或bind方法显式设置this的值。

 call方法允许你调用一个函数,并将this关键字的值设置为提供的值,然后传递一个参数列表。call的第一个参数是this将要指向的对象,后面的参数是传递给函数的参数。

function sayName() {

console.log("Name: " + this.name);

}

const person3 = { name: "bluemsun" };

sayName.call(person3); // 输出: Name: bluemsun

 apply方法的用法与call类似,区别在于apply接受一个参数数组,而不是参数列表。这在你想要传递一个参数数组给函数时非常有用。

function sayGreeting(greeting, punctuation) {

console.log(greeting + ", " + this.name + punctuation);

}

const person4 = { name: "bluemsun" };

sayGreeting.apply(person4, ["Hello", "!"]); // 输出: Hello, bluemsun!

 与call和apply不同,bind方法不会立即执行函数,而是返回一个新函数,这个新函数的this值被绑定到提供的值上。你可以稍后用新的参数调用这个新函数。

const person5 = { name: "bluemsun" };

const sayHello = sayName.bind(person5);

function sayName() {

console.log("Hello, " + this.name);

}

sayHello(); // 输出: Hello, bluemsun

7.严格模式:在严格模式下(使用'use strict';),全局作用域中的this值为undefined。

"use strict";

function myFunction() {

console.log(this);

}

myFunction();



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。