前端面试100问(11-21)
内容的起源来自于掘金上的一篇文章——《前端 100 问:能搞懂 80% 的请把简历给我》
木易杨前端进阶,《前端 100 问:能搞懂 80% 的请把简历给我》
系列笔记:
- 前端面试100问(1-10)
- 前端面试100问(11-21)
题11:算法手写题
已知如下数组:
var arr = [[1,2,2],[3,4,5,5],[6,7,8,9,[11,12,[12,13,[14]]]],10];
编写一个程序将数组扁平化并去除其中重复部分数据,最终得到一个升序且不重复的数组。
答: 参见 https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/8
这道题稍微有点复杂,即使了解了其中的知识点,想要完全独立手写一个方法出来还是很难。跳过。
题12:JS异步解决方案的发展历程以及优缺点
题13:Promise构造函数是同步执行还是异步执行,那么then方法呢?
答:经过前面几个问题的学习,这道题我可以答一下了。我的理解是Promise里面的代码是立即执行的,相当于是同步,resolve结果后,then()里的代码时异步的。
题14:情人节福利,如何实现一个new?
答:这道题到底在考什么?涉及到哪些知识点呢?懵~
看《每日壹题及答案汇总》讨论区
答案:先理清楚new关键字调用函数的具体过程,那么写出来就很清楚了
- 首先创建一个空的对象,空对象的__proto__属性指向构造函数的原型对象
- 把上面创建的空对象赋值构造函数内部的this,用构造函数内部的方法修改空对象
- 如果构造函数返回一个非基本类型的值,则返回这个值,否则上面创建的对象。
function _new(fn, ...arg) { var obj = Object.create(fn.prototype) const result = fn.apply(obj, ...arg) return Object.prototype.toString.call(result) == '[object Object]' ? result : obj; }
function mynew() { // 1.创建一个新对象 const obj = Object.create({}); // 也可以写成 const obj = {} // 2.将this指向该对象 let Fn = [].shift.call(arguments); // 把构造函数分离出来 let returnObj = Fn.apply(obj, arguments); // 通过apply将this指向由Fn变为obj // 3.将新对象的原型指向构造函数的原型 obj.__proto__ = Fn.prototype; // 4.返回对象(如果构造函数有返回对象,那么就返回构造函数的对象,如果没有就返回新对象) return Object.prototype.toString.call(returnObj) == '[object Object]' ? returnObj : obj; }
题16:谈谈你对TCP三次握手和四次握手的理解
插播一提
题60:已知如下代码,如何修改才能让图片宽度为300px?注意下面代码不可修改。
<img src="1.jpg" style="width:480px!important;" />
答:
方法一:css方法max-width:300px;覆盖样式 (亲测有效)
max-width: 300px;
方法二:transform: scale(0.625); 按比例缩放图片(亲测有效)
transform: scale(0.625);
方法三:js方法
document.getElementsByTagName("img")[0].setAttribute("style", "width:300px!important;");
方法四:
box-sizing: border-box;
padding: 90px;
题17:A、B机器正常连接后,B机器突然重启,问A此时处于TCP什么状态?(超纲题)
答:因为B会在重启之后进入TCP状态机的listen状态,只要当A重新发送一个数据包,B端应该会主动发送一个带rst位的重置包来进行连接重置,所以A应该在syn_sent状态。
题18、19 React相关,先跳过
题20:介绍下npm模块安装机制,为什么输入npm install就可以自动安装对应的模块?
题21:有以下3个判断数组的方法,请分别介绍它们之间的区别和优劣
Object.prototype.toString.call() instanceof Array.isArray()
答:
1.Object.prototype.toString.call()
每一个继承Object的对象都有toString方法,如果toString方法没有重写的话,会返回[object type],其中type为对象的类型,但当除了Object类型的对象外,其他类型直接使用toString方法时,会直接返回都是内容的字符串,所以我们需要使用call或者apply方法来改变toString方法的执行上下文。
const an = ['Hello', 'An'] an.toString(); // "Hello,An" Object.prototype.toString.call(an); // "[object Array]"
这种方法对于所有基本的数据类型都能进行判断,即使是null和undefined
Object.prototype.toString.call('An') // "[object String]" Object.prototype.toString.call(1) // "[object Number]" Object.prototype.toString.call(Symbol(1)) // "[object Symbol]" Object.prototype.toString.call(null) // "[object Null]" Object.prototype.toString.call(undefined) // "[object Undefined]" Object.prototype.toString.call(function(){}) // "[object Function]" Object.prototype.toString.call({name: 'An'}) // "[object Object]"
Object.prototype.toString.call()常用于判断浏览器内置对象时。
2.instanceof
instanceof的内部机制是通过判断对象的原型链中是不是能找到类型的prototype
但instanceof只能用来判断对象类型,原始类型不可以。并且所有对象类型instanceof Object都是true
[] instanceof Object; // true
3.Array.isArray() 用来判断对象是否为数组
Array.isArray优于instanceof,因为Array.isArray能检测iframes
var iframe = document.createElement('iframe') // undefined document.body.appendChild(iframe) <iframe>#document</iframe> xArray = window.frames[window.frames.length - 1].Array; // ƒ Array() { [native code] } var arr = new xArray(1, 2, 3); // undefined Array.isArray(arr) // true arr instanceof Array // false
Array.isArray的缺点是在老浏览器需要polyfill
假如不存在Array.isArray(),则在其他代码之前运行下面的代码将创建该方法。
if (!Array.isArray) { Array.isArray = function(arg) { return Object.prototype.toString.call(arg) === '[object Array]' } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理