1. 如何判断一个变量的类型是数组还是对象
因为数组和对象,typeof操作的返回值都是 object,所以我们需要用别的操作来区分它们的类型。
通过 constructor
var arr = [1, 2];
var obj = { name: 'obj1' };
console.log(arr.constructor === Array); // true
console.log(obj.constructor === Array); // false
通过 instanceof 运算符
console.log(arr instanceof Array); // true
console.log(obj instanceof Array); // false
通过 Object.prototype.toString
console.log(Object.prototype.toString.call(arr)); // [object Array]
console.log(Object.prototype.toString.call(obj)); // [object Object]
2. 简单表述一下前端的路由是如何实现的
早期的时候,路由是交由后端处理的,url中的每个路径都有相应的处理逻辑,后端已经都帮你写好了,所以没前端什么事。但是后端路由存在一个问题,就是每次切换页面都要重新向服务器发送请求,这样就造成了一个延迟的问题,用户体验不大好,页面复杂的话服务器也亚历山大。
前端路由实现主要有两种方式:
- 利用hash
在 HTML5 的 history API 出现之前,前端的路由都是通过 hash 来实现的。hash 的好处在于能兼容低版本的浏览器,它的标志就是 url 里带有 #。
实现原理:Web 服务不会解析 hash,也就是说 url 中 # 后面的部分 Web 服务会自动忽略,但 location.hash 可以取到这部分, 然后通过 hashchange 事件可以监听 location.hash 的变化,从而进行相应的处理。
localhost:8080/#/index
console.log(location.hash) // #/index
- 利用H5的History
H5新增了两个API,history.pushState 和 history.replaceState,结合 window.onpostate 事件一起形成了一种新的路由方式。
history.pushState 和 history.replaceState 都可以在不刷新页面的情况下改变 url 地址并操作浏览器的历史记录。不同之处在于,pushState会增加一条新的历史记录,而replaceState则会替换当前的历史记录。
这种模式下的路由没有 #,会看着美观一点,但是需要后台配置支持,不然会报404, vue-router 文档里也提到了这一点并给出了处理方法。
3. 截取字符串 abcdefg 中的 efg
没什么难的,但是我在答题的时候脑袋抽风,怎么都想不起来 substr() 方法,明明平时用到的次数还蛮多的,惊呆。
function getStr() {
var str = 'abcdefg';
var str2 = ''
if (/efg/.test(str)) {
str2 = str.substr(str.indexOf('efg'), 3);
}
return str2;
}
4. 用 JavaScript 给数组[1,1,2,3,4,4]去重
平常开发中数组的操作几乎都是用 lodash 完成的,所以看到这种题目的第一反应就是 _.uniq([...]),呵呵。
方法一:
function fn1(arr) {
// 新建一个临时数组
var arr1 = [];
for(var i = 0; i < arr.length; i++) {
// 如果arr的第i项已经没有临时数组里,则push进临时数组
if (arr1.indexOf(arr[i]) === -1) arr1.push(arr[i])
}
return arr1;
}
方法二:
function fn2(arr) {
var arr2 = [];
arr.forEach((item) => {
// 利用 es6 的 Array.prototype.includes()
if (!arr2.includes(item)) arr2.push(item);
})
return arr2;
}
方法三:
function fn3(arr) {
// es6 的新数据结构 Set,类似数组,但成员的值唯一
var set = new Set(arr);
// Array.from 方法可以将 Set 结构转为数组
// 或者直接用扩展运算符(...)结构 Set
// return [...set]
return Array.from(set);
}
5. display 属性的值和作用
这个很基础了,记录一些常用的例子。
| 值 | 描述 |
|---|---|
| none | 该元素不会被显示 |
| block | 该元素显示为块级元素,且元素前后带有换行符 |
| inline | 默认。该元素显示为内联元素,元素前后没有换行符 |
| inine-block | 行内块元素(CSS2.1 新增的值) |
| table | 该元素作为块级表格(类似 table)显示,表格前后带有换行符 |
| inline-table | 该元素作为内联表格(类似 table)显示,表格前后没有换行符 |
| table-row | 该元素作为一个表格行(类似 tr)显示 |
| table-cell | 该元素元素会作为一个表格单元格(类似 td/th)显示 |
| inherit | 从父元素继承 display 的值 |
总结
这篇文章是几个月前跳槽面试的过程中写的,前前后后边工作边面试大概面了10来家吧。进了新公司后一直很忙,没能及时将其余的面试题写进文章里,等现在再去回忆发现已经想不起来了。
只能等下次有机会再慢慢补充了。