持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第36天,点击查看活动详情
目录
今日题
题目
实现一个函数isCircular
检测对象中是否存在循环引用
const a = {
age: 18,
}
a.loop = a
分析
- 我们可以将上面的代码放在浏览器控制台打印一下
- 控制台的输出会是
a.loop
的值是a
本身 - 为了方便检测,可以在遍历对象时,将对象的值存储起来
- 之后每次在遍历是都取出存储的值来判断是否已经存储过了
昨日题
题目
实现插入排序
答案
function sort(arr) {
for (let i = 1; i < arr.length; i++) {
//当前要处理的数
let temp = arr[i];
let j = i - 1;
while (j >= 0 && arr[j] > temp) {
//如果前一个数大于后一个数,将前一个数往后移一位
arr[j + 1] = arr[j]
j--
}
//此时的j是要处理的数排序后应该在的位置
arr[j+1] = temp
}
return arr;
}
解析
- 插入排序的原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入
- 在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间
- 所以我们首先默认传入数组的
arr[0]
为有序序列 - 其中
while
做的内容就是插入排序的核心 - 进入
while
的元素是for
循环中,当前元素比前面的有序序列要小 - 所以在
while
中进行插入 while
下面的arr[j+1] = temp
中,j是要处理的数排序后应该在的位置
今日题
答案
function isCircular (obj) {
const wm = new WeakMap()
let flag = false
function isLoop(obj) {
if (obj instanceof Object) {
if (wm.has(obj)) {
flag = true
return
}
}
wm.set(obj,true)
for (const key in a) {
if (obj[key] instanceof Object) {
isLoop(obj[key])
}
}
return flag
}
return isLoop(obj)
}
解析
- 对于判断是否存在循环引用,我们用
WeakMap
来做容器,来存储遍历对象的值 - 在
isLoop
中,第一个if
我们可以先跳过 - 之后就是先用
WeakMap
来存储当前的对象 - 之后遍历当前的对象,如果当前对象的值也是一个对象,那么我们就进行递归调用
- 下面我们来看第一个
if
中写了什么 - 首先也是对参数的类型进行判断,在其为
Object
的情况下 - 我们来判断
WeakMap
中是否已经存储了相同的值 - 如果已经
WeakMap
中的值和当前递归的参数相同,就表示存在循环引用 - 所以我们将
flag
置为true
,直接返回即可
关于每日一题的感悟
- 很高兴能够参与每日一题的制作,能够和读者小小的卖弄一下
- 在出题期间,也能够更清晰的感受到自身的不足,感谢每日一题的出现,让我更加一步认识了现在的状态
- 个人认为这也是一个不可多得的主动锻炼自己的机会
- 虽说每日一题会暂时告一段落,但我相信将来会有恢复的一天,再次祝愿每日一题恢复之时,我们都能更上一层楼
- 感谢每一个看完文章的读者,这是对创作者最大的鼓励
结语
此文章已收录至《JavaScript每日一题》专栏,如果你对本专栏有任何建议,欢迎反馈。如果你对此文章中的题目还有不懂的地方,那么请在评论区留言与大家一起讨论吧。创作不易,少年,就请留个赞再走吧!