总结一波, 先这样吧,慢慢再补充,有问题…
目录
-
- 一、JS部分:
-
- 1.原型链
- 2.闭包
- 3.手写Promise
- 4.数据类型判断
- 5.Map和Set
- 6.垃圾回收机制
- 7.安全随机数
- 8.贪心算法
- 9.js循环
- 10.ES6数组新方法
- 11.Math方法
- 12.深拷贝&浅拷贝
- 13.es2019了解多少
- 14. 隐式转换
- 15.在地址栏中输入一个网址,这个过程中发生了什么
- 16.js中哪些方法可以实现异步操作
- 17.常用的数组、字符串方法
- 18.阻止事件冒泡
- 19.取消默认事件
- 20. 简述cookie、localstorage、seesionstorage
- 21. js跨域如何解决
- 22.webpack proxy跨域
- 23.js继承的实现
- 24.事件冒泡和事件捕获
- 25.this的指向
- 26. 箭头函数和普通函数的重要区别
- 27.require和import的区别
- 28. call apply bind 有什么区别?
- 29. async和defer的区别
- 二、HTML部分
- 三、Css部分
- 四、浏览器部分
- 五、Vue部分
- 六、vue-router篇
- 七、vuex篇
- 八、axios篇
- 九、框架
- 十、性能优化篇
- 十一、HTTP篇
- 十二、WebSocket
- 项目相关(不重要)
一、JS部分:
1.原型链
当访问一个对象的属性时,如果在对象的内部不存在,就会通过__proto__一直向上去找,直到null。
- 对象(除了null)中都有__proto__属性,函数是特殊的对象有__proto__和prototype两种属性。
- __proto__为隐式原型,指向它的构造函数的原型对象(prototype)。
- prototype为显式原型,是函数独有的(能够被当作构造函数使用的函数才有),指向函数的原型对象。它的作用就是让该函数所实例化的对象们,共享属性和方法
PS:
基本数据类型也有__proto__属性,但基本类型的值本质是个密封对象,不能增加、修改、删除属性。
- 引用类型和基本类型的主要区别,就是对象的生存期。
- 使用new操作符创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内存中。
- 而自动创建的基本类型,它的对象只存在于一行代码执行的瞬间,然后立即被销毁。这以意味着我们不能在运行时为基本类型添加属性和方法。
2.闭包
含义:访问了另一个函数作用域内的变量的函数。通常通过嵌套函数去实现。
function foo() {
var a = 1
function bar() {
a++
console.log(a)
}
return bar
}
const myFoo = foo()
myFoo()
好处:
- 缓存变量,参数和变量不会被垃圾回收机制回收
- 保存私有变量
- 实现方法和属性的私有化
坏处:容易导致内存泄漏
3.手写Promise
4.数据类型判断
typeof
:返回7种数据类型:number,string,boolean,undefined,symbel,object,functioninstanceof
:用来判断对象和数组 ([ ] instanceof Array)Array.isArray([ ])
判断数组的方法Array.isPrototypeOf([ ])
判断数组constructor
: 指向构造函数,原型链上的方法,所以不能用来判断null和undefined
Object.prototype.toString.call()
- - 相对来说最准确的方式
综合:
function gettype(obj) {
var type = typeof obj;
if (type !== 'object') {
return type;
}
//如果不是object类型的数据,直接用typeof就能判断出来
//如果是object类型数据,准确判断类型必须使用Object.prototype.toString.call(obj)的方式才能判断
return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1');
}
5.Map和Set
- Map()
map是一组键值对的结构,具有极快的查找速度。解决了JavaScript的对象键必须是字符串的问题。在map中,Number或者其他数据类型也可以作为键。
var m = new Map(); // 空Map
m.set('Adam', 67); // 添加新的key-value /或修改
m.has('Adam'); // 是否存在key 'Adam': true
m.delete('Adam'); // 删除key 'Adam'
m.get('Adam'); // undefined
- Set()
Set和Map类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在Set中,没有重复的key。
var s1 = new Set(); // 空Set
var s = new Set([1, 2, 3, 3, '3']);
s; // Set {1, 2, 3, "3"}
s.add(4);
s; // Set {1, 2, 3, "3", 4}
s.delete(3);
s; // Set {1, 2, "3", 4}
//数组去重 百试不爽
var arr=[...new Set([1,2,1,2,3])]
// [1, 2, 3]
6.垃圾回收机制
- 标记清除:在运行时给内存所有变量加上标记,然后去除掉在执行环境中的变量和被这些变量引用的变量。剩下的带有标记的变量视为准备删除的变量,最后垃圾回收机制在下周期运行时,释放这些变量,回收占用的空间
- 引用计数:引用表保存了内存里所有资源的引用次数。这个数为0时,就说明用不到了,就释放。
7.安全随机数
Math.random() : 返回介于 0(包含) ~ 1(不包含) 之间的一个随机数。该函数不是加密安全的随机数生成器。
window.crypto.getRandomValues(typedArray) : 返回非0的正整数,可以获取符合密码学安全性要求的随机值。
typedArray是一个基于整数的 TypedArray,其可以是 Int8Array、Uint8Array、Int16Array、 Uint16Array、 Int32Array 或 Uint32Array。
//生成随机随机数
var arr = new Uint16Array(8);
var crypto = window.crypto || window.webkitCrypto
|| window.mozCrypto || window.oCrypto || window.msCrypto;
window.crypto.getRandomValues(arr);
// 生成UUID
window.crypto.randomUUID();
详情参考:
1.JS 安全随机数 window.crypto及其兼容性
2.深入JS getRandomValues和Math.random方法
瞻仰一下大佬博客:张鑫旭的个人主页
总的来说:
Math.random() 随机数并不是实时生成的,而是直接生成一组随机数(64个),并放在缓存中。当这一组随机数取完之后再重新生成一批,放在缓存中。并且是可以被模拟、计算出来的。
getRandomValues() 方法的底层实现是没有缓存的,并且是实时生成的,因此,性能上是要比 Math.random() 差的
8.贪心算法
贪心算法以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。
//你有两个孩子和三块小饼干,2个孩子的胃口值分别是1,2。
//你拥有的饼干数量和尺寸都足以让所有孩子满足。
//所以你应该输出2.
输入: g = [1,2], s = [1,2,3]
输出: 2
var findContentChildren = function(g, s) {
g.sort(asc);
s.sort(asc);
let gp = 0,
sp = 0;
while (sp < s.length && gp < g.length) {
// 发现满足条件的饼干,喂饱一个孩子
if (s[sp] >= g[gp]) {
gp++;
}
// 继续找下一块饼干
sp++;
}
return gp;
function asc(a, b) {
return a - b;
}
};
console.log(findContentChildren([1,2,2,4,6,7,8,8,8,9,9], [1,3,4,4,5,8,9]))//6
具体参考:
9.js循环
for...of
语句在可迭代对象包括: Array,Map,Set,String,TypedArray,arguments 对象等等.弥补了弥补了forEach
和for-in
循环的短板- for in 遍历的是可枚举属性,for of 遍历的是可迭代属性
10.ES6数组新方法
-
forEach()
和map()
forEach()会修改原来的数组,不会返回执行结果。map()方法会得到一个新的数组并返回。
map的执行速度会更快。 -
filter()
创建一个新数组, 返回符合条件的元素。 -
reduce()
官方:对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。
简单来讲,他的主要作用,就是可以取到上次遍历的返回值。进而做累加等操作 -
some()
判断数组中是不是,至少有1个元素,通过了被提供的函数。 -
every()
指数组内的所有元素是否都能通过某个指定函数 -
Array.from()
:
用于将类似数组的对象和可遍历对象转为真正的数组 -
Array.of()
:
用于将一组值,转换为数组。
用来弥补数组构造函数Array()
的不足,基本上可以用来替代Array()
或new Array()
-
copyWithin()
:
将指定位置的成员复制到其他位置,然后返回当前数组,会修改当前数组。 -
find()
和findIndex()
find:找出 第一个 符合条件的数组成员
findIndex: 返回 第一个 符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1 -
fill()
使用给定值,填充一个数组。用于空数组的初始化非常方便。 -
entries()
,keys()
和values()
用于遍历数组。它们都返回一个遍历器对象。
keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历 -
includes()
表示某个数组是否包含给定的值,方法返回一个布尔值。 -
flat()
,flatMap()
flat:用于将嵌套的数组“拉平”,变成一维的数组。返回一个新数组
flatMap:对原数组的每个成员执行一个函数,然后对返回值组成的数组执行flat()方法,返回一个新数组。 -
at()
接受一个整数作为参数,返回对应位置的成员,主要是为了解决运算符[]
不支持负索引。
使用方法列举太臃肿,都放在另一篇了;
实例移步:
ES6数组新方法
旧的数组方法:
js数组方法
11.Math方法
- Math.abs() 返回绝对值
- Math.ceil(),Math.floor() 向上取整和向下取整
- Math.max(),Math.min() 最大值和最小值
- Math.round() 四舍五入
- Math.random() 随机数
- Math.pow() 指数运算
- Math.sqrt() 平方根
- Math.log() 自然对数
- Math.exp() e的指数
12.深拷贝&浅拷贝
基本类型:
引用类型:
访问一个引用类型,需要先从栈中获取该对象的指针,然后再通过指针访问堆内存对应的数据。
浅拷贝只拷贝这个对象的指针,原来的对象和拷贝的对象指向的是堆内存中的同一个东西,彼此之间的操作会互相影响。
深拷贝则会在堆内存中重新分配内存,拥有不同的地址,但值是一样的。
- 浅拷贝的方法:“=”赋值、"…"展开运算符、Object.assign() // 一层深拷贝
- 深拷贝: JSON.parse(JSON.stringify())、递归拷贝、var newObj = Object.create(oldObj)、第三方库lodash.clonedeep
详情:
关于深浅拷贝的那些事
13.es2019了解多少
String.prototype.trimStart()
/String.prototype.trimEnd()
头\尾的空格文本去掉Object.fromEntries()
键值对还原成对象结构Array.prototype.flat()
/Array.prototype.flatMap()
数组展平
[1, 2, [3, 4]].flat();// [ 1, 2, 3, 4 ]try...catch
catch的参数改为可选JSON.stringify()
加强格式转化JSON.parse()
添加了对行分隔符(\u2028) 和段落分隔符(\u2029)的支持
14. 隐式转换
- 数字运算:
“+”:将表达式的值转换为String(仅当有一个是String类型);
“-”:将表达式的值转换为Number; - “.”
被隐式转换为对象;
var a = 2;
console.log(a.toString()); // ‘2’; a被转换为对象,可以调用方法 - “if语句”
判断的条件表达式会被隐式转换为Boolean类型 - “==”
JS的非严格匹配时,会进行隐式类型转换
15.在地址栏中输入一个网址,这个过程中发生了什么
先查找缓存,有缓存直接返回资源给浏览器进程,网络请求结束
没有缓存文件或者缓存过期,则会 真正进入网络请求流程:
- 使用DNS解析,寻找服务器的ip
- TCP连接
- 发送HTTP请求
- 服务器处理HTTP请求并返回报文
- 浏览器解析渲染页面
- 连接结束
16.js中哪些方法可以实现异步操作
(1)定时器都是异步操作
(2)事件绑定都是异步操作
(3)promise
(4)回调函数可以理解为异步
(5)async await
(6)$nextTick
17.常用的数组、字符串方法
-
数组:
-
增(添加元素)
push(…items):用途: 向数组末尾添加一个或多个元素。是否改变原数组: 是。
unshift(…items):用途: 向数组开头添加一个或多个元素。是否改变原数组: 是。
concat(…arrays):用途: 合并数组,返回一个新数组。是否改变原数组: 否。 -
删(删除元素)
pop():用途: 移除并返回数组的最后一个元素。是否改变原数组: 是。
shift():用途: 移除并返回数组的第一个元素。是否改变原数组: 是。
splice(start, deleteCount):用途: 从指定位置删除元素。是否改变原数组: 是。
slice(start, end):用途: 返回子数组,不改变原数组。是否改变原数组: 否。 -
改(修改元素或顺序)
splice(start, deleteCount, …items):用途: 删除或替换元素,并可插入新元素。是否改变原数组: 是。
reverse():用途: 反转数组顺序。是否改变原数组: 是。
sort([compareFunction]):用途: 对数组排序。是否改变原数组: 是。
fill(value, start, end):用途: 用固定值填充数组的一部分或全部。是否改变原数组: 是。 -
查(查找元素或信息)
indexOf(item):用途: 返回元素第一次出现的索引,不存在则返回 -1。是否改变原数组: 否。
lastIndexOf(item):用途: 返回元素最后一次出现的索引,不存在则返回 -1。是否改变原数组: 否。
includes(item):用途: 判断数组是否包含某个元素。是否改变原数组: 否。
find(callback):用途: 返回第一个满足条件的元素。是否改变原数组: 否。
findIndex(callback):用途: 返回第一个满足条件的元素的索引。是否改变原数组: 否。
some(callback):用途: 判断是否有元素满足条件。是否改变原数组: 否。
every(callback):用途: 判断是否所有元素都满足条件。是否改变原数组: 否。
-
-
对象
-
增(添加属性)
Object.assign(target, …sources):用途: 将一个或多个源对象的属性复制到目标对象。 -
删(删除属性)
delete 操作符 用途: 删除对象的属性。 -
改(修改属性)
Object.defineProperty(obj, prop, descriptor):用途: 定义或修改对象的属性(可设置属性特性如 writable, enumerable 等)。
Object.freeze(obj):用途: 冻结对象,使其不可修改。 -
查(查找属性或信息)
Object.keys(obj):用途: 返回对象自身可枚举属性的数组。是否改变原对象: 否。
Object.values(obj):用途: 返回对象自身可枚举属性值的数组。是否改变原对象: 否。
Object.entries(obj):用途: 返回对象自身可枚举属性的键值对数组。是否改变原对象: 否。
obj.hasOwnProperty(prop):用途: 判断对象是否包含指定属性(不包括原型链)。是否改变原对象: 否。
Object.getOwnPropertyDescriptor(obj, prop):用途: 返回对象指定属性的描述符。是否改变原对象: 否。
Objec
-