摘要
从来都是看别人整理的面试题,是时候自己整理一份自己面试时被问到的前端面试题了。真正开始整理,才发现,即使只是整理,也需要花费不少时间,不过也确实可以加深记忆。
构造函数实例化的过程(new的实现)
- 创建一个新的空对象
- 将这个新的空对象的原型 proto ,指向构造函数的 prototype 属性,也就是空对象继承了构造函数的原型
- 将构造函数的 this 指向这个对象,开始执行构造函数内部的代码(用 call、apply )
- 最后
隐式return 构造后的对象(判断函数的返回值类型,如果是引用类型,就返回这个引用类型的对象。)
// 这个是阮一峰博客写的new命令简化内部流程
function _new(/* 构造函数 */ constructFunction, /* 构造函数参数 */ params) {
// 将 arguments 对象转为数组
var args = [].slice.call(arguments);
// 取出构造函数
var constructor = args.shift();
// 创建一个空对象,继承构造函数的 prototype 属性
var context = Object.create(constructor.prototype);
// 执行构造函数
var result = constructor.apply(context, args);
// 如果返回结果是对象,就直接返回,否则返回 context 对象
return (typeof result === 'object' && result != null) ? result : context;
}
// 实例
var actor = _new(Person, '张三', 28);
- 注意:
- new 只能返回一个对象,要么是实例对象,要么是return语句指定的对象
- 在构造函数中显式(手动)return 对象类型则会直接返回该对象,切断和构造函数的联系
- 可以在构造函数内部使用 new.target 属性来判断是否使用new调用
typeScript
有了解过泛型吗?什么时候需要用到泛型?
- 泛型是指在定义函数/接口/类时,不预先指定具体的类型,而是在使用的时候再指定类型限制的一种特性
- 当需要定义一个参数类型与返回值类型不确定的函数时
typeScript的类型推断是什么?
在没有明确指出类型的地方,类型推论会帮助提供类型 TypeScript文档-类型推论
用async修饰符去修饰一个函数的话,这个函数的返回值类型是什么?
被修饰的函数返回一个Promise对象 MDN-async函数
typescript里面的装饰器有用过吗?
随着ts和es引入类,在一些场景下需要额外的特性来支持标注或修改类及其成员 TypeScript文档-装饰器
浏览器
输入url到页面显示
- 输入 URL,先解析协议、主机、端口、路径等信息,构造一个 http 请求
- 发起 http 请求之前进行DNS域名解析
- tcp 连接
- http 请求
- 服务器处理请求并返回 http 报文
- 浏览器渲染页面
- 断开连接
DNS域名解析
- 递归查询:
- 浏览器、操作系统、路由器都会缓存一些 URL 对应的 IP 地址,统称为 DNS 高速缓存,就是为了加快 DNS 解析速度,不必每次都到根域名服务器中区查询
- 浏览器缓存--系统缓存--路由器缓存--ISP(网络服务提供商)缓存 2.迭代查询:
- 局部的 DNS 服务器并不会自己向其它服务器进行查询,而是把能够解析的域名服务器 IP 地址返回给客户端,客户端不断地向这些服务器进行查询,直到查询了位置(只会帮客户端查询到相关服务器 IP 地址,然后客户端自己去查询)
- 根域名服务器--顶级域名服务器--主域名服务器
浏览器渲染页面过程
- 解析 HTML,构建 DOM 树
- 解析 CSS,构建 CSS 规则树
- 合并 DOM 树和 CSS 规则,生成 render 布局树
- render布局树(Layout/reflow),负责各元素尺寸、位置的计算
- 绘制render树(paint),绘制页面像素信息
2. 如果头部有js脚本,会不会阻塞页面解析?
- 默认情况下,浏览器是默认同步加载js脚本的,所以渲染引擎遇到 script 标签就会停下来,等到执行完js脚本,再继续向下渲染
- 不阻塞的方法:(1)改变 script 标签位置,放在 body 标签最后面(2)异步加载 script,使用 async/defer 属性
- async 浏览器会异步下载脚本,这个过程不阻碍页面解析,等到脚本下载完成立即执行,执行脚本的过程页面会停止解析
- defer 浏览器会异步下载脚本,这个过程不阻碍页面解析,等页面解析完成才执行脚本
vue相关
watch 和 computed 的区别
- watch 中的函数不需要调用,computed 内部的函数调用时不需要加()
- watch 属性监听,监听属性的变化,computed 计算属性,通过属性计算而得来的属性
- watch 属性一变化就变化,主要用来监听某些特定数据的变化,从而进行一些业务逻辑的操作;computed 函数中所依赖的属性发生改变的时候才变化,主要用于对于任何复杂逻辑或者一个数据属性在它所依赖的属性发生变化时,也要变化的情况
- computed函数必须用 return 返回
Vue3 和 Vue2 有什么不一样
- 实例化方法不同:Vue2 通过 new Vue(),Vue3 通过 createApp 实例化
- 全局API改变:Vue2 中全局 API 挂在 Vue 中,Vue3 的全局 API 挂在实例 app 中
- Vue2使用选项类型 API(Options API),选项型 API 在代码里分割了不同的属性,data、computed、methods 等,Vue3 新增组合式 API(Composition API),可以用 function 来分割,代码会更加简便和整洁
- vue3 支持多根节点
- 生命周期命名不同,Vue3 的以 on 开头,并且需要引入才能使用
- 响应式原理:Vue2 是 Object.defineProperty,Vue3 是使用 Proxy(es6新特性)
- Vue3 由 ts 重写,相比于 Vue2 更好地支持 ts
Vue2 如何动态添加路由
- 利用 vue-router 的
addRoutes方法可以动态添加路由。
为什么要用 key 值,key 值的类型有限制吗?可以用中文吗?
- 提供给虚拟 DOM 的唯一标识,为了更高效的更新虚拟 DOM
- key 可以是 string 或者 number
自定义指令的一些使用场景
举一个最常用的vue特性?例如minxs
methods里面的方法可以作为props递给子组件吗?可以,会有什么副作用吗?为什么官方不推荐这种做法?
可以讲一下nuxt是什么吗?或者说这个项目里面nuxt是用来做什么?在项目中为什么要用,为什么需要依赖这个东西?
React相关
react 常用的构子函数
- useEffect:可以在函数组件中执行副作用操作(类似于类组件生命周期钩子)
- useState:让组件有 state 状态,并进行状态数据的读写操作
- useReducer: useState 的替代方案,用于逻辑较复杂且包含多个子值,或者下一个 state 依赖之前的 state
- useRef:可以在任意函数组件中存储/查找组件内的标签或任意其它数据
怎么实现组件引入的?
- 函数式组件
- 类组件
有了解过类组件吗?
react里面useEffect使用场景?
拓展题 提到了依赖值,就问如果单纯在function component(函数组件)里面let一个变量,当这个变量变化时,会再执行一次函数吗?
在函数式组件里面声明一个函数,然后把这个函数名作为useEffect的依赖项可以吗?
可以,但是每次执行这个函数就会引起useEffect重新执行
小程序
1.讲一下小程序负责的模块
2.小程序登录流程
小程序上传图片怎么压缩
- 使用官方提供的接口 wx.compressImage
- 安装第三方压缩包
- 通过压缩图片大小,利用canvas重绘得到压缩图片
其它
vite 和 webpack 有什么区别?
- 开发阶段运行项目的时候需要执行 webpack 打包命令,打包完成后将项目放入开发服务器中然后启动服务器,请求服务器直接给予打包结果,这些过程是在内存中完成的,所以开发阶段每次修改代码运行就会运行打包,如果依赖太多运行就会很慢
- vite 相对于 webpack,在开发阶段效率高得多,vite 在开发阶段没有打包过程,直接启动一个服务器,请求一个模块到开发服务器,开发服务器编译模块,根据页面所需要的依赖去加载文件,加载完成后,开发服务器把编译结果返回给页面
- 打包到生产环境时,vite 使用传统的 rollup 进行打包,主要优势在开发阶段,另外由于 vite 利用 ES Module,因此代码中不可以使用 CommonJS
websocket 有使用过吗?
为什么要使用 ssr(服务端渲染)?有什么好处?
- 首屏加载时间,服务端直接渲染出 HTML 字符串模板,浏览器可以直接显示,不再依赖 js 渲染(CSR 客户端渲染)
- SEO 友好, 因为服务端渲染输出到浏览器是完备的 HTML,使得搜索引擎能抓取到真实的内容,利于 SEO
需要注意的问题- 虽然 ssr 能快速呈现页面,但是在UI框架(比如React)加载成功之前,页面没法进行交互
- 更多的服务器负载。由于 ssr 需要依赖 Node.js 服务渲染页面,会占用服务器更多的CPU资源
- TTFB 第一字节时间会变长,因为 ssr 相对于 CSR 需要在服务端渲染更多HTML片段,因此加载时间会变长
webpack有相关的应用经验吗?或者有看过一些文档吗?
可以将一个webpack里面的核心概念吗?
webpack大概会配置一些什么?
git
git常用的命令有哪些
commit错了会怎么样,比如提交错了会怎么样?
查看两边代码对比的命令?
笔试题
隐式转换(考查Object.toString()和Object.valueOf())
'[object Object]' == {}返回什么?
返回true,因为这里进行了隐式转换,{}.toString()等于[object Object]
拓展题:[]+{} == "[object Object]"返回什么?
返回true,{}.toString()=[object Object], [].toString()=''
{}+[] == 0?
返回true
Object.prototype.proto 返回?
null
写一个判断变量是否为数组的表达式?
- a instanceOf Array 检验构造函数的prototype是否出现在对象的原型链中的任意位置
- a.constructor === Array 实例的构造函数constructor指向实例本身
- Object.prototype.String.call(a) === '[object Array]' 获取对象不同的类型
- Array.isArray(a) 用于确定传递的值是否为一个数组
写一个电话号码的正则表达式?
/^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/
简述javaScript的并发模型与事件循环
JavaScript有基于事件循环的并发模型,事件循环负责执行代码、收集和处理事件以及执行队列中的子任务 MDN并发模型与事件循环
简述块级格式化上下文
用于决定块级盒的布局及浮动相互影响范围的一个区域 MDN文档:块格式化上下文是web页面的可视css渲染的一部分,是块级盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域 MDN块格式化上下文