weakMap和Map的区别
weakMap弱引用,不影响垃圾回收器的工作
大数据量渲染优化,后端一次性返回10万条数据
- vxe-table
- 多行数据长任务计算使用Web.worker
- setTimeOut分页渲染
- 也可以 使用requestAmimationTrame代替setTimeOut
- 文档碎片+requestAmimationTrame
前端数据埋点
-
手动埋点
-
可视化埋点
-
无痕埋点:也叫自动埋点、全埋点。即对全局所有事件和页面加载周期进行拦截埋点
-
页面埋点:统计用户进入或者离开页面的信息(页面浏览次数-pv、浏览页面人数-uv、页面停留时长、设备信息)
-
点击埋点:统计用户在页面浏览中触发的点击事件。如按钮、导航或者图片的点击次数
-
曝光埋点:统计具体元素是否得到有效曝光
-
约定规范,通过统一接口来处理埋点逻辑
手写题(现场常考)
1. 金额格式化(保留两位小数)
js
function formatMoney(val) {
val = val.toString().replace(/[^0-9.]/g, '')
if (val.split('.').length > 2) val = val.slice(0, -1)
return Number(val || 0).toFixed(2)
}
2. 手机号脱敏
js
function maskPhone(phone) {
return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
}
3. 防抖(搜索 / 输入用)
js
function debounce(fn, delay) {
let timer
return (...args) => {
clearTimeout(timer)
timer = setTimeout(() => fn(...args), delay)
}
}
JS 基础 & 手写题答案
1. 防抖(高频手写)
js
function debounce(fn, delay) {
let timer = null
return function (...args) {
clearTimeout(timer)
timer = setTimeout(() => fn.apply(this, args), delay)
}
}
2. 节流
js
function throttle(fn, delay) {
let flag = true
return function (...args) {
if (!flag) return
flag = false
setTimeout(() => {
fn.apply(this, args)
flag = true
}, delay)
}
}
3. 手机号脱敏
js
function maskPhone(phone) {
return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
}
4. 金额格式化
js
function formatMoney(num) {
return Number(num).toFixed(2)
}
5. 深拷贝简单版
js
function deepClone(obj) {
if (obj === null || typeof obj !== 'object') return obj
const res = Array.isArray(obj) ? [] : {}
for (let k in obj) {
res[k] = deepClone(obj[k])
}
return res
}
如何判断一个对象是空对象
使用 JSON 自带的.stringify 方法来判断:
使用 ES6 新增的方法 Object.keys()来判断:
编写一个数组去重的方法
function sort(arr){
for(var i=0; i < arr.length; i++) {
for (var j = i+1; j < arr.length; j++) {
if (arr[i] == arr[j]) {
arr.splice(j,1)
j-- // 删除一个元素后,后面的元素会依次往前,下标也需要依次往前
}
}
}
return arr
}
冒泡算法排序
for (var i=0; i < arr.length-1;i++) {
for (var j=0;j < arr.length-1-i; j++) {
if (arr[j]>arr[j+1]) {
var temp = arr[j]
arr[j] = arr[j+1]
arr[j+1] = temp
}
}
}
元素水平垂直居中的方法有哪些?如果元素不定宽高呢?
- 利用定位+margin:auto
<style>
.father{
width:500px;
height:300px;
border:1px solid #0a3b98;
position: relative;
}
.son{
width:100px;
height:40px;
background: #f0a238;
position: absolute;
top:0;
left:0;
right:0;
bottom:0;
margin:auto;
}
</style>
<div class="father">
<div class="son"></div>
</div>
- 利用定位+margin:负值
<style>
.father {
position: relative;
width: 200px;
height: 200px;
background: skyblue;
}
.son {
position: absolute;
top: 50%;
left: 50%;
margin-left:-50px;
margin-top:-50px;
width: 100px;
height: 100px;
background: red;
}
</style>
<div class="father">
<div class="son"></div>
</div>
- 利用定位+transform
<style>
.father {
position: relative;
width: 200px;
height: 200px;
background: skyblue;
}
.son {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
width: 100px;
height: 100px;
background: red;
}
</style>
<div class="father">
<div class="son"></div>
</div>
- table布局
设置父元素为display:table-cell,子元素设置 display: inline-block。利用vertical和text-align可以让所有的行内块级元素水平垂直居中
<style>
.father {
display: table-cell;
width: 200px;
height: 200px;
background: skyblue;
vertical-align: middle;
text-align: center;
}
.son {
display: inline-block;
width: 100px;
height: 100px;
background: red;
}
</style>
<div class="father">
<div class="son"></div>
</div>
flex布局
<style>
.father {
display: flex;
justify-content: center;
align-items: center;
width: 200px;
height: 200px;
background: skyblue;
}
.son {
width: 100px;
height: 100px;
background: red;
}
</style>
<div class="father">
<div class="son"></div>
</div>
grid布局
<style>
.father {
display: grid;
align-items:center;
justify-content: center;
width: 200px;
height: 200px;
background: skyblue;
}
.son {
width: 10px;
height: 10px;
border: 1px solid red
}
</style>
<div class="father">
<div class="son"></div>
</div>
实现一个trim方法
- 通过原型创建字符串的trim()
//去除字符串两边的空白
String.prototype.trim=function(){
return this.replace(/(^\s*)|(\s*$)/g, "");
}
//只去除字符串左边空白
String.prototype.ltrim=function(){
return this.replace(/(^\s*)/g,"");
}
//只去除字符串右边空白
String.prototype.rtrim=function(){
return this.replace(/(\s*$)/g,"");
}
2. 通过函数实现
function trim(str){
return str.replace(/(^\s*)|(\s*$)/g, "");
}
实现一个三角形(CSS绘制三角形主要用到的是border属性,也就是边框)
div {
width: 0;
height: 0;
border-top: 100px solid red;
border-right: 100px solid transparent;
}
画一条0.5px的线
采用transform: scale()的方式,该方法用来定义元素的2D 缩放转换(transform: scale(0.5,0.5);)
js手写基础深拷贝函数(处理对象 / 数组)
function deepClone1(target) {
// 1. 如果不是对象/数组,直接返回原值(基本数据类型)
if (typeof target !== 'object' || target === null) {
return target;
}
// 2. 判断是数组还是对象,初始化结果
const result = Array.isArray(target) ? [] : {};
// 3. 递归遍历所有属性
for (const key in target) { // 只拷贝自身属性,排除原型链属性
if (target.hasOwnProperty(key)) {
result[key] = deepClone(target[key]);
}
}
return result;
}
function deepClone2(obj) {
// 基本类型直接返回
if (typeof obj !== 'object' || obj === null) {
return obj;
}
// 数组 or 对象
let clone = Array.isArray(obj) ? [] : {};
// 递归拷贝
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = deepClone(obj[key]);
}
}
return clone;
}