梳理一波面试题

176 阅读3分钟

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中的每个路径都有相应的处理逻辑,后端已经都帮你写好了,所以没前端什么事。但是后端路由存在一个问题,就是每次切换页面都要重新向服务器发送请求,这样就造成了一个延迟的问题,用户体验不大好,页面复杂的话服务器也亚历山大。

前端路由实现主要有两种方式:

  1. 利用hash

在 HTML5 的 history API 出现之前,前端的路由都是通过 hash 来实现的。hash 的好处在于能兼容低版本的浏览器,它的标志就是 url 里带有 #。

实现原理:Web 服务不会解析 hash,也就是说 url 中 # 后面的部分 Web 服务会自动忽略,但 location.hash 可以取到这部分, 然后通过 hashchange 事件可以监听 location.hash 的变化,从而进行相应的处理。

localhost:8080/#/index
console.log(location.hash) // #/index
  1. 利用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来家吧。进了新公司后一直很忙,没能及时将其余的面试题写进文章里,等现在再去回忆发现已经想不起来了。

只能等下次有机会再慢慢补充了。