一、数据类型:
- 基本数据类型(名值存储在栈内存中):
Boolean、Number、String、undefined、Null、Symbol - 引用数据类型 (名存在栈内存中,值存在于堆内存中,但是栈内存会提供应该引用的地址指向堆内存中的值):
Object、Array、Function - 数据类型判断:
typeof、instanceof、Object.prototype.toString.call()
二、this指向问题:
- 箭头函数this指向:-
箭头函数没有自己的this,看其外层的是否有函数,如果有,外层函数的this就是内部箭头函数的this,如果没有,则this是window - 箭头函数特点:-
没有原型、 没有构造函数,不能new实例对象、 本身没有this指向,this指向父级
三、闭包:(静态作用域)
- 概念:
定义在函数内部的函数。里面的函数可以访问外面函数的变量,外面的变量是这个内部函数的一部分 - 作用:
使用闭包可以访问函数中的变量。2.可以使变量长期保存在内存中,生命周期比较长。 - 应用场景:
函数作为参数传递。2.函数作为返回值 - 缺点:
闭包不能滥用,容易导致内存泄露,影响网页的性能
四、拷贝
1. 浅拷贝:浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。修改时原对象也会受到影响。
方法:
- 利用 = 赋值操作符实现浅拷贝。
- 数组的浅拷贝一般使用 slice、concat。
- 数组浅拷贝 - 遍历 。
- 对象浅拷贝 - Object.assign()。
- 对象浅拷贝 - 扩展运算符
2. 深拷贝:深拷贝就是在拷贝数据的时候,将数据的所有引用结构都拷贝一份
1、`用 JSON.stringify 把对象转换成字符串,再用 JSON.parse 把字符串转换成新的对象 ` JSON.parse(JSON.stringify())
2. 递归方法:
function _deepClone(source) {
let target;
if (typeof source === 'object') {
target = Array.isArray(source) ? [] : {}
for (let key in source) {
if (source.hasOwnProperty(key)) {
if (typeof source[key] !== 'object') {
target[key] = source[key]
} else {
target[key] = _deepClone(source[key])
}
}
}
} else {
target = source
}
return target
}
五、防抖与节流
1. 防抖:
概念:将多次高频操作优化为只在最后一次执行 应用:用户输入,只需在输入完成后做一次输入校验即可
/**
* 防抖 (debounce)将多次高频操作优化为只在最后一次执行
*
* @param {Function} fn 需要防抖函数
* @param {Number} delay 需要延迟的毫秒数
* @return {Function}
*
*/
function debounce(fn, delay = 1000) {
let timer;
return function (...args) {
// 如果在定时时间内再次触发事件, 则清空定时器,重新计时
if (timer) clearTimeout(timer);
// 事件不再触发
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
2. 节流:
概念:每隔一段时间后执行一次,将高频操作优化成低频操作 应用:滚动条事件 或者 resize 事件
/**
* 节流(throttle)将高频操作优化成低频操作,每隔 100~500 ms执行一次即可
*
* @param {Function} fn 需要防抖函数
* @param {Number} timer 需要延迟的毫秒数
* @return {Function}
*
*/
// 节流:在固定时间内,函数只能触发一次
// 就是指连续触发事件但是在 n 秒中只执行一次函数。**节流会稀释函数的执行频率。
function throttle(fn, timer = 3000) {
// 定义上一次时间戳
let prev = 0;
return function (...args) {
// 延展参数语法
// 定义下一次时间戳
let now = new Date();
if (now - prev > timer) {
// 时间差大于一秒才触发函数(事件回调函数)
fn.apply(this, args);
// 更新时间戳
prev = now;
}
};
}
六:重绘与回流:
- 浏览器渲染机制(采用流式布局模型):
1.浏览器会把`HTML`解析成`DOM Tree`,解析`css`构建`render`树(将css代码解析成树形的数据结构,然后结合DOM合并成render树)
2.有了`RenderTree`,我们就知道了所有节点的样式,然后计算他们在页面上的大小和位置,最后把节点绘制到页面上
- 重绘:
概念:
- 回流(
回流必定会发生重绘,重绘不一定会引发回流):
概念:
七、Array常见操作方法:
- map: 遍历数组,返回回调返回值组成的新数组
- forEach: 无法break,可以用try/catch中throw new Error来停止
- filter: 过滤
- some: 有一项返回true,则整体为true
- every: 有一项返回false,则整体为false
- find: 返回一个符合的{}
- findIndex: 返回序号
- join: 通过指定连接符生成字符串
- push / pop: 末尾推入和弹出,改变原数组, 返回推入/弹出项
- unshift / shift: 头部推入和弹出,改变原数组,返回操作项
- sort(fn) / reverse: 排序与反转,改变原数组
- concat: 连接数组,不影响原数组, 浅拷贝
- slice(start, end): 返回截断后的新数组,不改变原数组
- splice(start, number, value...): 返回删除元素组成的数组,value 为插入项,改变原数组
- indexOf / lastIndexOf(value, fromIndex): 查找数组项,返回对应的下标
- reduce / reduceRight(fn(prev, cur), defaultPrev): 两两执行,prev 为上次化简函数的return值,cur 为当前值(从第二项开始)
- flat: 数组拆解, flat: [1,[2,3]] --> [1, 2, 3]
七、Object 常见操作方法:
- Object.keys(obj): 获取对象的可遍历属性(键)
- Object.values(obj): 获取对象的可遍历属性值(值)
- Object.entries(obj): 获取对象的可遍历键值对
- Object.assign(targetObject,...object): 合并对象可遍历属性
- Object.is(value1,value2): 判断两个值是否是相同的值
八、原型/构造函数/### 实例:
概念:
- 1.原型(prototype): 一个简单的对象,用于实现对象的 属性继承。可以简单的理解成对象的爹。在 Firefox 和 Chrome 中,每个JavaScript对象中都包含一个__proto__ (非标准)的属性指向它爹(该对象的原型),可obj.__proto__进行访问。
//1.构造函数
function Person(name, age) {
this.name = name
this.age = age
}
//2.原型对象
console.log(Person.prototype)
//给原型对象添加方法
Person.prototype.eat = function () {
console.log('吃东西')
}
Person.prototype.learn = function () {
console.log('学习')
}
//3.实例对象
let p1 = new Person('张三', 20)
let p2 = new Person('李四', 25)
console.log(p1, p2)
console.log(p1.eat === p2.eat)//true
- 2. 构造函数: 可以通过new来 新建一个对象 的函数。
function createPerson(name, age, sex) {
this.name = name
this.age = age
this.sex = sex
}
let p1 = new createPerson('张三', 20, '男')
let p2 = new createPerson('李四', 30, '男')
- 3. 实例: 通过构造函数和new创建出来的对象,便是实例。 实例通过__proto__指向原型,通过constructor指向构造函数。