深度拷贝、异常、this、防抖与节流
深度拷贝
开发时复制一个对象会出现一些问题: 对象的属性值是对象,复制的时候只是复制了引用,修改复制的对象的属性值会影响原对象的属性值。
浅拷贝和深拷贝只针对引用数据类型。
浅拷贝浅拷贝只是复制了对象的引用,修改复制的对象的属性值会影响原对象的属性值。
拷贝对象:Object.assign({}, obj) 或者 ...obj
拷贝数组:Array.prototype.concat() 或者 [...arr]
但是浅拷贝会存在一些问题,比如拷贝对象的属性值是对象,修改拷贝对象的属性值会影响原对象的属性值。
因为浅拷贝只拷贝了最外面一层的对象,内部的对象只是拷贝了引用。
深拷贝深拷贝是指完全复制一个对象,即使对象的属性值是对象,修改复制的对象的属性值不会影响原对象的属性值。
通过递归实现
递归很容易发生栈溢出,所以需要限制递归的深度,加退出条件
12345678910function deepClone(newObj, oldObj) { // newObj是新对象,oldObj是旧对象 for (let key in oldObj) ...
JS构造函数及原型
创建对象的三种方式
使用对象字面量
通过new Object()创建对象
12const obj = new Object()obj.name = 'Tom'
通过构造函数创建对象
1234567function Person(name, age) { this.name = name this.age = age}const p = new Person('Tom', 18)const p2 = new Person('Jerry', 20)
构造函数中的this指向当前对象,通过new关键字调用构造函数时,this指向新创建的对象。
构造函数的首字母大写,约定俗成。
实例化构造函数时没有参数可以省略,不需要写return,返回值是新创建的对象。
❓实例化执行过程
创建新对象
构造函数this指向新对象
执行构造函数代码,修改this,添加新的属性
返回新对象
实例成员&静态成员
实例成员: 通过构造函数创建的对象称为实例对象,实例对象中的属性和方法称为实例成员。
静 ...
JS函数、解构赋值
☁️ 函数函数提升与变量提升相似,是指函数在声明之前即可被调用。
会把所有函数声明提升到当前作用域的最前面,只提升函数声明,不提升函数调用。
123456// 函数提升fn()function fn() { console.log('fn')}
函数表达式必须先声明赋值再调用
函数参数
动态参数:函数的参数个数不固定,可以通过arguments对象获取所有参数。argument是伪数组,可以通过下标访问。
12345678910function add() { let sum = 0 for (let i = 0; i < arguments.length; i++) { sum += arguments[i] } return sum}console.log(add(1, 2, 3, 4)) // 10console.log(add(1, 2, 3, 4, 5)) // 15
剩余参数:允许将不定数量的参数表示为一个数组。
12345 ...
JavaScript作用域
💭局部作用域
函数作用域:函数内部声明的变量只能在函数内部访问
函数的参数也是局部变量
不同函数内部的同名变量互不影响
函数执行完毕后,局部变量会被销毁
块级作用域:let和const声明的变量只能在块级作用域内访问(ES6新增)
块级作用域:{}包裹的代码块,比如if、for、while等
代码块内部声明的比那两外部有可能无法访问(var声明的变量可以访问)
💭全局作用域
全局作用域:在函数外部声明的变量,所有函数内部都可以访问
为window对象动态添加的属性也是全局变量(不推荐)
函数中未使用var、let、const声明的变量也是全局变量(不推荐)
尽可能避免全局变量,会造成全局变量污染
💭作用域链本质是底层的变量查找机制,当访问一个变量时,会先在当前作用域查找,如果当前作用域查找不到则会依次逐级查找父级作用域直到全局作用域。
嵌套关系的作用域串联起来形成了作用域链
相同作用域链中按着从小到大的规则查找变量
子作用域能够访问父作用域的变量,反之不行
💭JS垃圾回收机制GC(Garbage Collection)JS中内存的分配和回 ...
正则表达式
1. 什么是正则表达式正则表达式是一种用来匹配字符串的强有力的工具,它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,就认为是匹配的。
在JavaScript中,正则表达式是对象,通常用来检索、替换那些符合某个模式的文本。匹配(验证表单)、替换(过滤敏感词)、提取(爬虫)等。
2.语法定义正则表达式12345const str = 'hello world'// 1. 字面量定义:`/正则表达式/修饰符`const reg = /hello/// 2. 构造函数定义:`new RegExp('正则表达式', '修饰符')`const reg = new RegExp('hello')
判断字符串是否符合规则1console.log(reg.test(str)) // true
检索(查找)符合规则的字符串1regObj.exec(str) // 返回一个数组,包含匹配的字符串,index,input
3.元字符
普通字符:字母、数字,仅仅描述字符本身。
元字符:具有特殊含义 ...
Web APIs学习 --BOM(三)
Window对象1.BOM对象
BOM是浏览器对象模型,是浏览器提供的对象模型,用于操作浏览器窗口。
全局对象,document、location、navigator、history都是window的属性。
2.定时器-延时函数
setTimeout:延时执行一次,返回值是一个定时器ID。123setTimeout(() => { console.log('延时执行')}, 1000)
清除延时函数1clearTimeout(timer)
3.JS执行机制
浏览器有两个引擎:JS引擎和渲染引擎。
单线程执行,同一时间只能执行一个任务。
同步和异步任务:同步任务会阻塞后续任务,异步任务不会阻塞后续任务。
同步任务在主线程执行,形成一个执行栈。
异步任务相关会放到任务队列中,等待主线程空闲时执行。
异步任务有三种类型:普通事件、资源加载、定时器。
一旦执行栈中所有的同步任务执行完毕,就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。
事件循环:主线程从任务队列中读取事件,这个过程是循环不断 ...
Web APIs学习 --DOM(二)
日期对象用来表示时间的对象,可以得到当前系统时间。
实例化12const date = new Date() // 获取当前时间const date2 = new Date('2021-01-01') // 获取指定时间
时间对象方法返回的数据不适用于直接使用,该怎么转换为实际开发中常用的格式呢?
123456789const date = new Date()console.log(date) // 2021-01-01T00:00:00.000Zconsole.log(date.getFullYear()) // 2021 年份console.log(date.getMonth()) // 0 月份 0-11 注意是从0开始!console.log(date.getDate()) // 1 日期console.log(date.getDay()) // 5 星期 0-6 0是星期天console.log(date.getHours()) // 8 小时console.log(date.getMinutes()) // 0 分钟console.log(date. ...
Web APIs学习 --DOM(一)
Web APIs
尽量用const,少用let,不用var。
数组和对象用const,数组和对象的元素和属性可以改变。因为const只是保证变量指向的内存地址不变,不保证内存地址的值不变。
基本认知
Web API就是使用js去操作html和浏览器
分类:DOM(文档对象模型)、BOM(浏览器对象模型)
DOM是用来呈现以及与任意HTML或XML文档交互的API,主要操作网页内容,比如对页面元素进行移动、大小、添加删除等操作。开发网页内容特效和实现用户交互
DOM树将HTML文档以树状结构直观的表现出来,文档树直观的体现了标签与标签之间的关系。
DOM树的节点类型
元素节点:HTML标签
文本节点:HTML文本
属性节点:HTML属性
注释节点:HTML注释
DOM对象浏览器根据html标签生成的js对象,所有的标签属性都可以在这个对象上面找到,修改这个对象的属性会自动映射到标签身上。
12// 获取元素对象,在html中是标签,在js中获取到的是对象。const div = document.querySelector('div')
DOM的核心思想 ...
JavaScript基础语法学习
JavaScript是什么?做什么?
是一种运行在客户端(浏览器)的编程语言,实现人机交互效果。
网页特效、表单验证、数据交互。
服务端编程(Node.js)。
组成:ECMAScript(语言基础)、Web API(浏览器提供的API)(包括页面文档对象模型DOM、浏览器对象模型BOM)
DOM:操作文档,比如对页面元素进行移动、大小、添加删除等操作。
BOM:操作浏览器,比如页面弹窗,检测窗口宽度,存储数据到浏览器等。
JavaScript书写位置
内部嵌入:在HTML文件中使用<script>标签嵌入JavaScript代码。(上方)原因:浏览器会按照代码在文件中的顺序加载HTML,如果先加载的JavaScript想修改下方的HTML,可能由于HTML尚未加载而失效。
外部引入:在HTML文件中使用<script>标签引入外部JavaScript文件。1234<body> <!--中间写内容也会被忽略--> <script src="my.js"></script> < ...
JavaScript异步编程
📌 1. JavaScript 为什么需要异步?JavaScript 是 单线程(Single-threaded)语言,它的执行方式是逐行执行,但有时候代码的执行可能会遇到等待:
你去点咖啡(等待制作)。
你从服务器请求数据(等待网络)。
你读取一个文件(等待磁盘)。
如果JavaScript只能同步执行,遇到等待时,整个程序都会卡住,无法继续执行。为了解决这个问题,JavaScript引入了异步编程。
📌 2. 回调函数(Callback)—— 传统异步最原始的异步方案是回调函数(callback),即当任务完成时,调用一个函数来处理结果。
💡 例子:回调函数点咖啡1234567891011function orderCoffee(callback) { console.log("开始制作咖啡..."); setTimeout(() => { console.log("咖啡制作完成 ☕"); callback("☕ 咖啡"); }, ...