js面试题
unshift定义
Array.prototype.myunshift=function(){
const len=arguments.length
for (var i=len-1; i>=0; i--){
const e=arguments[i]
this.splice(0,0,e)
}
return this.length;
}
数组去重
Array.prototype.unique=function(){
return Array.from(new Set(this))
}
Array.prototype.unique1=function(){
let arr=[]
for (let i=0; i<this.length,i++){
if(!arr.includes(this[i])){
arr.push(this[i])
}
}
return arr
}
Array.prototype.unique2=function(){
return this.filter((v,idx)=>{
return this.indexOf(v,0)===idx;
})
}
获取指定范围内的随机数
function fn(min,max){
// (min,max)
// return Math.round(Math.random()*(max-min-2)+min+1);
// [min,max]
// return Math.round(Math.random()*(max-min)+min)
// (min,max]
// return Math.ceil(Math.random()*(max-min)+min)
//[min,max)
return Math.floor(Math.random()*(max-min)+min)
}
打印100以内的质数
let count
for(let i=2;i<=100;i++){
for(let j=1;j<i;j++){
if(i%j==0){
count++;
}
}
if(count==2){
console.log(i);
}
count=0;
}
提取url的参数
let url='https://ali.com?a=1&b=2&c=3'
function queryUrlParams(url){
let u=url.split('?')[1]
const us=new URLSearchParams(u)
const params=Object.fro mEntries(us.entries())
return params
}
数组随机排序
let arr=[1,2,3,4,5]
function sortArr(arr){
for(let i=0;i<arr.length;i++){
let ri=parseInt(Math.random()*arr.length)
let cn=arr[i]
arr[i]=arr[ri]
arr[ri]=cn
}
return arr
}
arr.sort(()=>Math.random()-0.5)
flatten
let a=[1,2,[3,4,[5,6]]]
const flatten=function(arr){
while(arr.some(v=>Array.isArray(v))){
arr=[].concat(...arr)
}
return arr
}
const f=function(arr){
return [].concat(...arr.map(v=>(Array.isArray(v)?f(v):v))
}
两数之和
const nums=[1,2,3,5]
const target=0
function twoSum(nums,target){
for(let i=0;i<nums.length;i++){
const num=nums[i]
const ti=nums.indexOf(target-num)
if(ti>-1&&ti!=i){
return[i,ti]
}
}
}
发布订阅
class EventEmitter{
handlers={}
on(type,handler,once=false){
if(!this.handlers[type]){
this.handlers[type]=[]
}
if(!this.handlers[type].includes(handler)){
this.handlers[type].push(handler)
handler.once=once
}
}
once(type,handler){
this.on(type,handler,true)
}
off(type,handler){
if(this.handlers[type]){
this.handlders[type]=this.handlers[type].filter(h=>{
return h!=handler
})
}
}
trigger(type){
if(this.handlers[type]){
this.handlers[type].forEach(handler=>{
handler.call(this)
if(handler.once){
this.off(type,handler)
}
})
}
}
}
首屏加载优化
- dns解析
- dns缓存优化
- dns预加载策略
- 对浏览器页面下载解析渲染过程优化
- 精简html代码
- 优化css文件结构
- 合理放置js代码
- 将首屏渲染的css样式放html中
- 延迟加载图片
- 文件体积优化
- 减少css js 体积
- js defer属性
微前端中的应用隔离
- css隔离
- css module 或命名空间的方式,添加特定前缀postcss 插件打包添加特定前缀
- 微应用之间css隔离 link style 标签打标去标
- shodowdom
- js隔离
- window全局事件 sandbox 沙箱机制
- js with window.proxy 对象
es6模块与commonjs模块的相同点和区别
相同点:
- 对引入对象进行赋值,即对对象内部属性的值改变
区别:
- commonjs模块运行时加载es6模块编译时输出接口
- commonjs require 同步加载模块,es6 import异步
- commonjs 对模块的浅拷贝,es6只存在只读不改变其值,指针指向不能变 const
输入url
- 浏览器缓存-系统缓存-路由缓存
- http请求 dns ip
- tcp 连接 三次握手
- 发送http 请求 请求数据包
- 服务器收到请求 返回数据到浏览器
- http 响应
- 读取页面内容 渲染 解析 html
- 生成 dom 树 解析 css js 渲染页面
深拷贝浅拷贝
-
基本数据类型 栈
-
引用类型 堆
-
浅拷贝
- 只拷贝一层
- object.assign
- array.prototype.slice()
- array.prototype.concat()
- 扩展运算
-
深拷贝
- _.clonedeep()
- $.extend()
- json.stringify()存在undefined symbol弊端
- 手写循环递归
虚拟dom
- virual dom 跨平台能力 rn weex
- js对象描述真实dom
- dom操作引起的性能问题 diff
pwa
- 渐进式网页应用
- app manifest service worker webpush
promise值穿透
- .then .catch 期望的是函数,传入非函数则会发生值穿透
js延迟加载
- defer
- async 异步加载
- 动态创建dom
- settimeout
- js最后加载
异步编程
- 回调函数
- promise
- generator
- async
pnpm
- 包安装速度快
- 磁盘空间利用率高
promise
- 异步编程,没有回调地狱,