1. get和post的区别
- 携带数据:get(请求头),post(请求体或请求头)
- 语义:get(获取数据),post(创建数据)
- 缓存:get可以被缓存,post不会
- 安全性:都不安全,但post比get更安全一点,密码等敏感信息放到post上
2. Event Loop
async function async1(){
console.log('async1 start'); // 2
await async2() // 3
console.log('async1 end'); // 6
}
async function async2(){
console.log('async2');
}
console.log('script start'); // 1
setTimeout(function(){
console.log('setTimeout'); // 8
},0)
async1();
new Promise(function(resolve){
console.log('promise1'); // 4
resolve();
}).then(function(){
console.log('promise2'); // 7
})
console.log('script end'); // 5
运行顺序
- 创建函数——async1
- async2创建
- 输出
script start
- 设置定时器——宏任务A(异步)
- async1执行——输出
async1 start
- 运行
await async2
——执行async2等待返回的结果(微任务B),然后再输出async2
- new Promise的时候会立即把执行上下文函数执行,所以输出
pormise1
- new Promise里面的resolve函数为微任务C
- 输出最后一行
script end
- 此时第一阶段已经完成,接下来运行事件队列(event queue)
- 微任务先执行,宏任务后执行。按先后顺序执行微任务B、C,再执行宏任务A
- 此时输出
async1 end
、promise2
、setTimeout
微任务
promise
process.nextTick
;宏任务setTimeout
setInterval
I/O
script
3. 优化DOM
- 多个DOM操作合并为一次操作(文档碎片)
// 先附加到文档碎片中再一次性提交
var a = document.createDocumentFragment(); // 创建一个文档碎片
- 缓存DOM查询
const length = document.get('1').length
4. async/await
async(语法糖),原理就是promise
async function fun(){
const a = await // 后面跟promise对象
}
await搭配promise使用,实际是用同步的写法完成异步的编程
5.new Object()和Object.create()的区别
具体可看:https://www.cnblogs.com/leijee/p/7490822.html
const a = Object.create(null/obj); // 括号里面传原型方法
6. 斐波那契数列(1,1,2,3,5,8,…)
- 方案一:
function fibonaqi(count){
function fn (count,cur=1,next=1){
if(count==0) {
return cur;
} else {
return fn(count-1,next,cur+next);
}
}
return fn(count);
}
- 方案二:
获取单个值(数组)
function fibonaqi(n){
if(n<=1) return 1;
let arr = [1,1]
let i = n+1-2;
while(i>0){
let a = arr[arr.length-2], // 倒数第二个
b = arr[arr.length-1];
arr.push(a+b);
i--;
}
return arr[arr.length-1];
}
// 调用
fibonaqi(3) // 3
- 方案三:
简单的方法(递归)
function fb(n){
if(n-2>=0){
return fb(n-2) + fb(n-1)
} else {
return 1
}
}
7. 数组扁平化的N种实现方式
应用:把数组变成一维数组然后算总数
let arr = [
[1,2],
[3,4,5],
[6,7,8,9,[11,12,[12,13,[14]]]],10]
];
- 方案一:不考虑兼容的情况下(ES6)
arr = arr.flat(Infinity); // 里面填级数 这里表示的是无限级
- 方案二:转换为字符串
// 先转字符串,再用,拼接成数组,最后再循环
arr = arr.toString().split(',').map(item=>parseFloat(item))
- 方案三:循环验证是否为数组
while (arr.some(item=>Array.isArray(item))){
arr = [].concat(...arr)
}
8. 数组排序
例子数组:[12,8,24,16,1]
- 1. 冒泡排序
原理:每一轮比较后,当前数组中最大的放到末尾。一轮轮的比较,每轮都从第一项开始,拿出当前项A和后一项B进行比较,A>B则让两者交换位置
function bubble(ary){
let temp = null;
for(let i=0;i<ary.length-1;i++){
for(let j=0;j<ary.length-1-i;j++){
if(arr[j]>ary[j+1]){
temp = ary[j];
ary[j] = ary[j+1];
arr[j+1] = temp;
}
}
}
return ary;
}
let ary = [12,8,24,16,1];
ary = bubble(ary);
-
2. 插入排序
原理:将要排序的数组分成两部分,每次从后面的部分取出索引最小的元素插入到前一部分的适当位置 -
3. 快速排序
原理:快速排序法号称是目前最优秀的算法之一,实现思路是,将一个数组的排序问题看成是两个小数组的排序问题,而每个小的数组又可以继续看成更小的两个数组,一直递归下去,直到数组长度大小最大为2。
9. 数组去重
例子数组:[1,1,2,3,3,4,8,4,2]
- 1. Set集合
let arr = [...new Set(ary)]
// let arr = Array.from(new Set(ary))
- 2. 用当前项和后面的进行比较
for(let i=0;i<ary.length-1;i++){
let item = ary[i],
args = ary.slice(i+1);
if(arys.indexOf(item)>-1){
ary.splice(i,1); // splice删除会导致数组改变,这样i++会使数组坍塌,所以用i--
i--; // 性能不好,当前项一旦删除,后面索引和改变
}
}
- 3. 对象的键值对(key和value都是一个元素)
- 4. 相邻项的处理方案(用正则表达式)