css 实现自适应的正方形
1、css3 vw 单位
<div className="square"></div>
.square {
width: 100vw;
height: 100vw;
}
2、maging、padding 的百分比数值是相对于父元素的宽度计算的
.square {
width: 100%;
padding-top: 100%;
height: 0; // 不设置为 0 的话,内容会撑开高度
}
3、2 的方案会导致 max-height 失效,要利用伪元素撑开高度
.square {
overflow: hidden;
width: 100%;
&::after {
content: " ";
display: block;
padding-top: 100%;
}
}
treeshaking
import {xxx} from "xxx";
if (process.env.NODE_ENV === "development") {
xxx();
}
// xxx 会被 treeshaking 吗?
js 文件、css 文件、图片应该按照什么规则设置浏览器缓存
设置强缓存和协商缓存,强缓存失效就使用协商缓存,资源添加版本号,强制刷新缓存
JSON.stringify 深拷贝有什么缺点
1、Date 类型会变成字符串 2、正则对象会变成空对象 3、对象里的方法、undefined、Symbol 会丢失
JSON.stringify 有几个参数
Object.assign
- 将所有可枚举属性的值从一个或多个源对象
source复制到目标对象,第一个参数是目标对象,其他参数都是源对象,后面对象的属性会覆盖前面对象的属性 - 如果参数不是对象,会被转换为对象
- null 和 undefined 作为参数会报错
浅拷贝
- 如果某个源对象的属性是对象,那么拷贝的是这个属性的引用
- 多个源对象有同名属性,会被覆盖
用法场景
- 为对象添加属性或方法
- 克隆对象,只能克隆对象自身的属性,不克隆原型的属性
- 合并多个对象
实现对象的深拷贝
判断对象是否有循环引用
实现 Object.create
function Create(o){
function F(){}
F.prototype = o;
return new F();
}
prototype 上的引用类型属性会被实例共享,怎么解决
用正则将手机号中间四位变成星号
str.replace(/(/d{3})\d{4}(/d{4})/, "$1****$2");
react 的性能优化的点有哪些
redux 和 mobx 的区别
多维数组打平有哪些方式
- es6 flat 方法
arr.flat(n)// n 表示数组维度,Ifinity表示任意维度
- reduce+concat+递归
function flat(arr){
arr.reduce((pre,next) => {
return pre.concat(Array.isArray(next) ? flat(next) : next)
},[])
}
react同时设置多个setState,怎么做只让组件重新渲染一次
- react对多次状态更新会批量处理,同步代码中的setState会批量更新,异步代码(setTimeout、promise.then)的setState会触发多次更新;
- 可以使用useRef,不会触发多次更新;
- 将多个state变量合并到一个中;
判断空对象的方法有哪些
- object.entries()或Object.keys(),返回空数组
- JSON.stringify()转为"{}"
- for...in+额外变量,变量初始值设为true,若不为空对象,在循环里设置为false
实现深拷贝需要考虑哪些问题
- 需要考虑的点
- 日期格式
- 正则对象
- 循环对象引用
- 不能丢失原对象的原型
- 简易版
// 判断是否是对象
const isRefferenceObj = (value)=> typeof value === 'object' && typeof value !== null;
const deepCopy = (obj) => {
if (!isRefferenceObj(obj)) {
return obj;
}
let newObj = Array.isArray(obj)?[]:{};
Object.keys(obj)?.forEach(key => {
const value = obj[key];
newObj[key] = isRefferenceObj(value)?deepCopy(value):value;
})
return newObj;
}
- 完整版
const deepCopy = (obj,map=new WeakMap()) => {
if (obj.constructor === Date) {
return new Date(obj);
}
if (obj.constructor === RegExp){
return new RegExp(obj);
}
if (typeof obj !== 'object'||obj === null) {
return obj;
}
const prototype = Object.getPrototypeOf(obj);
const newObj = Object.create({},prototype)
// 通过map对象来防止循环引用
map.set(obj,true);
Reflect.ownKeys(obj)?.forEach(key => {
const value = obj[key];
if(typeof value !=='object'||typeof value===null){
newObj[key] = value;
} else {
if (map.has(value)) {
newObj[key] = map.get(value)
} else {
newObj[key] = deepCopy(value);
}
}
})
return newObj;
}
for 循环和 forEach里调用await,会有什么不同
- for会按照顺序输出,forEach会一次性输出并且不保证顺序
- 因为forEach内部就是一个函数,按循环执行,并没有异步的相关处理逻辑
怎么显示比12px更小的字体
- zoom
<style type="text/css">
.span1{
font-size: 12px;
display: inline-block;
zoom: 0.8;
}
.span2{
display: inline-block;
font-size: 12px;
}
</style>
<body>
<span class="span1">测试10px</span>
<span class="span2">测试12px</span>
</body>
- tramsform:scale()
<style type="text/css">
.span1{
font-size: 12px;
// scale只对能设置宽高的元素起作用,所以需要设置inline-block
display: inline-block;
-webkit-transform:scale(0.8);
}
.span2{
display: inline-block;
font-size: 12px;
}
</style>
<body>
<span class="span1">测试10px</span>
<span class="span2">测试12px</span>
</body>
对象数组去重
- filter+map
function uniqueArr(arr){
let map = new Map();
return arr.filter(item => {
if (!map.has(item.id)) {
map.set(item.id,true);
return true;
} else {
return false
}
})
// return arr.filter(item => !map.has(item.id)&&map.set(item.id,true))
}
0.2+0.3精度问题、大数据精度问题
- js 最多能精确到小数点后16位,所以可以按照小于这个位数做个精确度截取
function strip(num, precision = 12) {
return +parseFloat(num.toPrecision(precision));
}
- 将小数转成整数计算
/**
* 精确加法
*/
function add(num1, num2) {
const num1Digits = (num1.toString().split('.')[1] || '').length;
const num2Digits = (num2.toString().split('.')[1] || '').length;
const baseNum = Math.pow(10, Math.max(num1Digits, num2Digits));
return (num1 * baseNum + num2 * baseNum) / baseNum;
}
- 使用Math.js或BigDecimal.js
重复请求有哪些处理方法
css 不同大小的字体底部对齐
- 父元素设置
display:flex;子元素设置align-items:baseline