嗯,上次写blog已是几周前的事情了,其实已经积攒了不少小问题须要记录和分享了。可是在8月底,VK我一次经历了了携程、拼多多、腾讯、网易等多轮面试轰炸,忙得不可开交,有喜有忧的同时,仍是赶快记录了不足,把一些充满迷惑性的问题继续记录和学习。javascript
JavaScript老是给人以惊喜,学习不止,进步不断,今天继续补充JS容易搞错的几道笔试/面试题,为了秋招继续努力,欢迎一块儿为秋招努力的小伙伴共勉html
系列笔记:前端
1.VK的秋招前端奇遇记(一)java
2.VK的秋招前端奇遇记(二)node
4.VK的秋招前端奇遇记(四)github
这是一道巨坑的题目算法
先看下不少博客、文章总结的一个关于循环的区别是怎么说的编程
- map能够作链式操做、forEach不能够
- map有返回值,return、 forEach没有返回值
- for循环不用担忧兼容性问题,能够break跳出循环,是基础循环
- forEach不支持continue和break,是不能退出循环自己的。
上面这些比较,自己没有什么问题,可是当第三点和第四点结合的时候,就很容易让人有个推论:
map是能够跳出循环的,能够提早中断
然而,也的确有些面试官,认为forEach不能break,map是能够的跳出的
。 真的是这样的?
首先,众所周知,forEach
是不能用break提早中断循环的,若是使用了,会直接报错。好比如下:
var list = [1,2,3,4];
list.forEach(item => {
if(item === 2) {
break;
}
} )
复制代码
可是,若是真的想要停止? 由于会报错,这也提供给咱们一个思路,那就是用try..catch
把它保住,捕获错误。 可是,我的认为真是画蛇添足,应该没人会这么用。就很少作讨论了。
那么map
能够用break吗?
很显然,它也不行。因此若是有面试官问你,甚至告诉你"forEach和map的不一样,forEach不能够停止"时,你真的能够大胆回击:
Array.prototype.map
实现break,也是彻底不可能的请问如下程序中,person1
和person2
哪一个是Person的实例?其__proto__
分别指向谁?
function Person(name) {
this.name = name;
return {name: name}
}
var person1 = new Person('sam');
var person2 = Person('Lily')
复制代码
person1和person2都不是Person的实例
它们的'__proto__'指向Object
复制代码
这题题目的关键就是理解new
的过程,这也是常见的面试题之一了。若是遇到关键字new
,那么,函数就不仅仅是一个函数了:
this
this.name = name
this
固然,这里简化了这个过程,可是核心是这几步。 可是若是在隐式返回this
以前,提早返回了一个对象,那么就会退出函数了。 要知道,只有这个this
才是实例自己,它的__proto__
才指向构造函数,若是不能把this
返回出去,那么一切都是徒劳的。所以,这里不管是否new
,都返回的是一个新对象{}
。
这里,本身当时回答的很差,就引用别人博客整理的内容啦.
function fn1() {
var obj = {name: 'hanzichi', age: 10};
}
function fn2() {
var obj = {name:'hanzichi', age: 10};
return obj;
}
var a = fn1();
var b = fn2();
复制代码
fn1中定义的obj为局部变量,而当调用结束后,出了fn1的环境,那么该块内存会被js引擎中的垃圾回收器自动释放;在fn2被调用的过程当中,返回的对象被全局变量b所指向,因此该块内存并不会被释放。
标记清除:
定义和用法:当变量进入环境时,将变量标记"进入环境",当变量离开环境时,标记为:"离开环境"。某一个时刻,垃圾回收器会过滤掉环境中的变量,以及被环境变量引用的变量,剩下的就是被视为准备回收的变量。
到目前为止,IE、Firefox、Opera、Chrome、Safari的js实现使用的都是标记清除的垃圾回收策略或相似的策略,只不过垃圾收集的时间间隔互不相同。
引用计数:
定义和用法:引用计数是跟踪记录每一个值被引用的次数。
基本原理:就是变量的引用次数,被引用一次则加1,当这个引用计数为0时,被视为准备回收的对象。
垃圾回收器周期性运行,若是分配的内存很是多,那么回收工做也会很艰巨,肯定垃圾回收时间间隔就变成了一个值得思考的问题。
IE6的垃圾回收是根据内存分配量运行的,当环境中的变量,对象,字符串达到必定数量时触发垃圾回收。垃圾回收器一直处于工做状态,严重影响浏览器性能。
IE7中,垃圾回收器会根据内存分配量与程序占用内存的比例进行动态调整,开始回收工做。
说实话,这一块,本身没有很好的整理,可是目前准备秋招和毕设,没有更多的经历,只能待有空再深刻学习研究了。
请将如下表格,按年龄进行排序,使用原生JS,不容许使用任何第三方工具。
<table>
<thead>
<tr>
<th>name</th>
<th>age</th>
</tr>
</thead>
<tbody>
<tr>
<td>张三</td>
<td>17</td>
</tr>
<tr>
<td>李四</td>
<td>43</td>
</tr>
<tr>
<td>王五</td>
<td>22</td>
</tr>
<tr>
<td>小刘</td>
<td>9</td>
</tr>
<tr>
<td>黄三</td>
<td>20</td>
</tr>
</tbody>
</table>
复制代码
这个其实很easy了,只是我在写的时候,仍是调试了好几回,这里主要两点:
document.getElementsBytagNames
选择的对象,在dom的映射机制下,是双双绑定的;dom.appendChild()
方法,要保证参数是node节点。Array.sort()
方法,注意,只能用在Array上。var sortByAge = function () {
var tbody = document.getElementsByTagName('tbody')[0];
var items = tbody.getElementsByTagName('tr');
let arrayI = Array(...items); //将类数组转化为数组,使用sort方法
arrayI.sort((a,b)=> {
let ageA = a.getElementsByTagName('td')[1].innerText;
let ageB = b.getElementsByTagName('td')[1].innerText;
return ageA - ageB;
})
for(let i = 0; i<items.length; i++) {
tbody.appendChild(arrayI[i]); //依次插入,这里arrayI的每个元素都是原来的dom映射过来的实例。因此并非“创造”出了复制品,而是从新排序了
}
}
sortByAge();
复制代码
一天24小时,咱们将其折为每30分钟为一段,这样一天共有48段。咱们用1表示这段时间有效,0表示无效,好比10...
表示开始时间为00:00
持续了半个小时,技术时间为00:30
。111001..
则表示00:00~01:30
02:30~03:00
两个时间段。
要求写一个函数,对时间码进行转换:
输入:110100000000000000000000000000000000000000000000
输出: ["00:30~01:30", "01:00~02:00"]
这个是我视频面试时的一道编程题,因为时间紧,面对面试官有点小压力,因此就用了比较笨的方法实现了,后来也没有从新思考和优化,有好的思路和简单的方法的小伙伴欢迎交流。
如下思路:
startTime
;若是不是第一次,进行time
累加time
值进行累加,计算endTime
,并将时间段push到数组根据上面思路,代码以下:
function timeTransfer(str) {
var flag = false, //flag,判断是否第一次为1
time = 0, //时间记录值
n = str.length,
startTime, //开始时间
startHour, //开始的小时
startMin, //开始的分钟
endTime, //结束时间
endHour, //结束的小时
endMin, //结束的分钟
retTime = []; //最终返回的数组
for(let i = 0 ; i < n; i++) {
if(str[i] === '1') {
if(flag === false) { //判断是否为第一个1,若是是,根据i设定开始时间
startHour = parseInt(i/2);
startMin = i % 2 ? 0:30;
startTime = `${startHour > 9? startHour: '0' + startHour}:${startMin > 9 ? startMin : '0' + startMin}`;
flag = true; //置位 flag
}
time += 0.5; //时间累加
if(i === n-1) { //若是已经遍历到最后,那么计算结束时间(当str的末尾为1时,须要处理)
endHour = startHour + parseInt(time);
endMin = startMin + (time % 2 ? 0 : 30);
endTime = `${endHour > 9 ? endHour : '0' + endHour}:${endMin > 9 ? endMin : '0' + endMin}`;
retTime.push(`${startTime}~${endTime}`);
}
} else if (str[i] === '0') {
if(flag === false) { //若是为flase,表明前面不是1,继续下次循环
continue;
} else { //不然,计算结束时间
flag = false;
endHour = startHour + parseInt(time);
endMin = startMin + (time % 2 ? 0 : 30);
endTime = `${endHour > 9 ? endHour : '0' + endHour}:${endMin > 9 ? endMin : '0' + endMin}`;
retTime.push(`${startTime}~${endTime}`);
}
}
}
return retTime;
}
复制代码
以上程序,是跑通了的,虽然有点笨,可是勉强知足要求。