每日一题 (让我更优秀把!)
1.object、map和weakMap的区别
- 创建方式
- object 创建方式
const object = {}; const object1 = new Object(); const object2 = Object.creat({}); - map 创建方式
const map0 = new Map(); const map1 = new Map[{"key1":1,"key2":2,"key3":3}]; const map2 = new Map({[Symbol.iterator]:function*(){ yield ["key1","val1"]; yield ["key2","val2"]; yield ["key3","val3"]; } }); const map3 = new Map([[]]);
- object 创建方式
- 键值
Object 只能用数值、字符串或者符号作为键。 Map 可以使用任何JavaScript数据类型作为键。 - 选择
- 内存占用
- map占用大
- 插入性能
- 量大map优
- 查找速度
- object相对快
- 删除性能
- map
- 内存占用
- weakMap
- ES6新特性。
- 只接受对象作为键名。
- WeakMap的键名所引用的对象是弱引用,即会被垃圾回收机制执行,obj所引用的对象就会被回收。
- WeakMap不可遍历。
- WeakMap只有四个方法可以使用:get()、set()、has()、delete()。
cosnt map = new WeakMap(); map.set({},1);
2.async原理
- async实际为Generator的语法糖,Generator的函数的星号(*)替换称 async,将yield替换成await。
- 同步方式,执行异步操作。
- await 只能在async函数中使用,不然会报错
- async函数返回的是一个Promise对象,有无值看有无return值
- await后面最好接Promise
- generator 实现 async
function generatorToAsync(generatorFn){
return function(){
const gen = generatorFn.apply(this,arguments);
// 返回一个Promise
return new Promise((resolve,reject)=>{
function go(key,arg){
let res
try{
res = gen[key](arg)
}catch(error){
return reject(error)
}
//解构获得value和done
const {value,done} = res
if(done){
// 如果done为true 说明走完了,进行resolve(value)
return resolve(value);
}else{
// 如果done为false,说明没走完,还得继续走
return Promise.resolve(value).then(val=>go('next',val),err=>go('throw',err))
}
}
// 第一次执行
go("next");
})
}
}
3.你对于堆与栈的理解
-
栈(stack)
- 栈是一种特殊的列表,栈内的元素只能通过列表的一端访问,这一端被称为栈顶。栈被称为是一种后入先出(LIFO,last-in-first-out)的数据解构。由于栈具有后入先出的特点,所以在任何不在栈顶的元素都无法访问,为了得到栈底的元素,必须先拿掉上面的元素。
- 栈内存中变量一般在它的当前执行环境结束就会被销毁,被垃圾回收机制回收
-
堆(heap)
- 堆是一种经过排序的树形数据结构,每个结点都有一个值,通常指二叉堆。特点是根系欸但的数值最小(或最大),且根节点的两个子树也是一个堆。
- 实现优先队列,堆的存取是随意的。
- 堆内存中的变量只有在所有对它的引用都结束才会被会回收。
4.sort的底层原理
- 排序算法的术语
- 稳定 如果a原本在b前面,当a = b时,排序之后a仍然在b的前面
- 不稳定 如果a原本在b前面,当a = b时,排序之后a可能会出现在b的后面
- 内排序 所有排序操作都在内存中完成
- 外排序 由于数据太大,因此把数据放在磁盘中,而排序通过磁盘和内存的数据传说才能进行
- 时间复杂度 一个算法执行所耗费的时间
- 空间复杂度 运行完一个程序所需要内存的大小
- 基本排序算法
- 冒泡排序(BubbleSort) 最慢
- 比较相邻的元素,如果第一个比第二个大,就交换它们两个
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一堆,这样最终最大数被交换到最后的位置。
- 除了最后一个元素以为,针对所有的元素重复以上的步骤。
- 重复上述步骤,知道排序完成。
- 选择排序(SelctionSort)
- 插入排序(insertionSort) 最快
1 从第一个元素开始,该元素默认已经被排序
2 取除下一个元素,在已经排序的元素中从后向前扫描
3 如果该元素(已排序)大于新元素,将该元素移到下一位置
4 重复步骤3,知道找到已排序的元素小于或等于新元素的位置
5 将新元素插入到该位置
6 重复步骤2~5,知道排序完成
- 高级排序算法
- 希尔排序(Shell Sort)
- 归并排序(Merge Sort)
1 把长度为n的输入序列分成2个长度为n/2的子序列;
2 对这两个子序列分别采用归并排序;
3 将两个排序号的子序列合并成一个最终的排序序列
- 快速排序(Quicksort)
- 通过递归方式将数据依次分解为包含小元素和较大元素的不同序列,会不断重复这个步骤,知道所有的序全部为有序的,最后将这些子序列一次皮筋起来,就可以到拍好的数据。
- 希尔排序(Shell Sort)
- 冒泡排序(BubbleSort) 最慢
5.前端路由模式及其原理
- Hash 模式
- 原理 localtion.hash,即url中#后面的内容(即 '#search')
https://www.word.com#search - 特性
- url中hash值只是客户端的一种状态,也就是说向服务端发送请求时,hash部分不会被发送。
- hash值的改变,都会在浏览器的访问离职中增加一个记录。因此可以通过浏览器的回退、前进按钮控制hash的切换。
- 可以使用hashchange事件来监听hash的变化。
- a标签 设置href属性
<a href="#search">search</a> - js直接操作location.hash进行赋值,从而改变url触发 hashchange事件
location.hash = '#search'
- a标签 设置href属性
- 原理 localtion.hash,即url中#后面的内容(即 '#search')
- History 模式
- 原理 HTML5提供History API 来实现URL的变化。不刷新浏览器的情况下,操作浏览器的历史记录。history.pushState() 新增一个历史记录, history.replaceState() 替换当前的历史记录
- 特性
- pushState 和 repalceState的标题(title):一般浏览器会忽略,最好传入null;
- 可以使用popstate事件来监听url的变化;
- history.pushState()或history.replaceState()不会触发popstate事件,需要我们手动触发页面渲染;