Skip to content

鼓励作者:欢迎打赏犒劳

JavaScript 面试题

JavaScript 的基本功面试题无非包括 闭包、原型链、继承、作用域、执行栈、class 实现继承

它的手写面试题包括

数组扁平化、去重、排序

已知如下数组:var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];

编写一个程序将数组扁平化去并除其中重复部分数据,最终得到一个升序且不重复的数组

javascript
var arr = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10];

// 扁平化
let flatArr = arr.flat(Infinity);
// 去重
let disArr = Array.from(new Set(flatArr));
// 排序
let result = disArr.sort(function (a, b) {
    return a - b;
});
console.log(result);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
// Array.from 将类数组转成数组实例

数组去重

ES5

javascript
function unique(arr) {
    var res = arr.filter((item, index, array) => {
        return array.indexOf(item) === index;
    });
    return res;
}

ES6

javascript
function unique(arr) {
    return [...new Set(arr)];
}

数组扁平化

使用 Array.prototype.flat 就可以将多层数组拍平一层

javascript
[1, [2, [3]]].flat(Infinity); // [1, 2, 3]

ES5:递归

javascript
function flatten(arr) {
    var result = [];
    for (var i = 0, len = arr.length; i < len; i++) {
        if (Array.isArray(arr[i])) {
            result = result.concat(flatten(arr[i]));
        } else {
            result.push(arr[i]);
        }
    }
    return result;
}

ES6

javascript
function flatten(arr) {
    while (arr.some((item) => Array.isArray(item))) {
        arr = [].concat(...arr);
    }
    return arr;
}

数组对象去重

方法一:new Set + JSON.stringigy

javascript
const arr = [
	{id: 1, name: 'John'},
  	{id: 2, name: 'Jane'},
  	{id: 1, name: 'John'},
  	{id: 3, name: 'Bob'},
  	{id: 2, name: 'Jane'}
]

const set = new Set(arr.map(JSON.stringify));
// 先把每一项转成字符串,再在数组中通过 Set 去重
const uniqueArr = Array.from(set).map(JSON.parse);
// Array.from 将 Set 后的对象转换成 Array
// 再将去重的字符串还原成对象

console.log(uniqueArr);

方法二:reduce

javascript
const arr = [
	{id: 1, name: 'John'},
  	{id: 2, name: 'Jane'},
  	{id: 1, name: 'John'},
  	{id: 3, name: 'Bob'},
  	{id: 2, name: 'Jane'}
]

const uniqueArr = Object.values(arr.reduce((acc, cur) => {
  acc[cur.id] = cur;
  return acc;
}, {}));
// acc 累加值,cur 当前值,第二个参数是初始值initialValue
// Object.values() 对象转数组

方法三:filter

javascript
const arr = [
  {id: 1, name: 'John'},
  {id: 2, name: 'Jane'},
  {id: 1, name: 'John'},
  {id: 3, name: 'Bob'},
  {id: 2, name: 'Jane'}
];

const uniqueArr = arr.filter((item, index, arr) => {
    return arr.findIndex(t => t.id === item.id) === index
})

方法四:Map

javascript
const arr = [
  {id: 1, name: 'John'},
  {id: 2, name: 'Jane'},
  {id: 1, name: 'John'},
  {id: 3, name: 'Bob'},
  {id: 2, name: 'Jane'}
];

const map = new Map();
arr.forEach(item => map.set(item.id, item));

const uniqueArr = Array.from(map.values());

console.log(uniqueArr);

如何实现浏览器内多个标签页之间的通信?

三种。监听 localStorage、webworker、sharedworker

javascript
window.onstorage = (e: any) => {
    console.log(e);
};

js 延迟加载的方式有哪些?

defer 和 async

什么是 defer?

什么是 async?

动态创建 DOM 方式

按需异步载入 js

如何解决跨域问题?

如何统计当前页面出现过多少种 html 标签

javascript
new Set([...document.getElementsByTagName('*')].map((v) => v.tagName)).size;

求一个网页中出现次数最多的三种标签

javascript
const html = document.querySelector('html');
const htmlChild = html.children;
let obj = {};
function fn(children) {
    for (let i of children) {
        if (obj.hasOwnProperty(i.tagName)) {
            obj[i.tagName] = obj[i.tagName] + 1;
        } else {
            obj[i.tagName] = 1;
        }
        const child = i.children;
        if (child.length !== 0) {
            fn(child);
        }
    }
}
fn(htmlChild);
let tag = Object.entries(obj).sort((a, b) => b[1] - a[1]);

function result(array) {
    return array.slice(0, 3);
}
console.log(result(tag));

问:介绍 defineProperty 方法,什么时候需要用到

Array 的方法,那些会改变原数组,那些不会

改变数组:

shift、unshift、pop、push、reverse、sort、splice、fill、copyWidthin

不改变数组:

concat、join、slice、map、filter、forEach、some、every、reduce

垃圾回收

迭代器

类数组和数组的区别在哪里

相同点:都可用下标访问每个原生,都有 length 属性

不同点:数组的类型是 Array,类数组的类型是 object。即数组遍历可以用 for in 或 for,类数组只能用 for 循环

常见的类数组有:arguments、DOM 对象列表(document.querySelectorAll)

类数组转换为数组

  1. Array.prototype.slice.call(arrayLike, 0)
  2. [...arrayLike] 扩展运算符
  3. Array.from(arrayLike)

数组转换为类数组

javascript
var arr = [1, 2, 3, 4]
var obj = {}
[].push.apply(obj, arr)

代码题:手写进度条

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>进度条</title>
    <style>
        #progress-bar {
            width: 100%;
            height: 10px;
            background: gainsboro
        }

        #progress-slot {
            transition: all 0.5s;
            background: red;
            height:100%;
        }
    </style>
</head>
<body>
    <div id="progress-bar">
        <div id="progress-slot"></div>
    </div>
    <script>
        let timer = 0;
        function start() {
            const dom = document.getElementById('progress-slot')
            let width = 0;
            timer = setInterval(() => {
                width +=1;
                dom.style.width = width + '%'
                if (width >= 100) {
                    clearInterval(timer)
                }
            }, 150)
        }
        start()
    </script>
</body>
</html>

参考资料