🚩前端必备文档记录
注:知识无价,白嫖的知识更应珍惜。网上免费教材众多,学会筛选更利于成长!
类型 | 网站用途 | 网站链接 |
---|---|---|
教材类 | mdn(前端的百科全书) | https://developer.mozilla.org/zh-CN/ |
Javascript.info | https://zh.javascript.info | |
其他 | bilibili、开源博客、力扣、牛客… | |
进阶类 | github(代码仓库) | https://github.com/ |
Node.js中文网 | https://nodejs.cn/ | |
提效类 | 菜鸟工具 | https://www.jyshare.com/ 内含ChatGPT、豆包、Kimi、通义千问、文心一言等ai工具 |
ProcessOn思维导图 | 这是邀请链接哈:👉ProcessOn网址👈 | |
阿里巴巴矢量图标库 | https://www.iconfont.cn/ |
🚩html
🚩css
英文换行
word-break: break-all;
![](https://i-blog.csdnimg.cn/direct/2cd7749a03ae4f908221996ec4ce43a8.png)
文本省略
单行文本省略
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
多行文本省略
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2; // 文本显示几行
层叠上下文 z-index
不设置z-index值,默认值为auto
,啥也没有;
设置z-index值哪怕值为-1、0
也会创建层叠上下文
例如:有3个子盒子,那这3个子盒子的z-index只在设置了层叠上下文的父盒子里面生效
应用场景:例如有个自上而下的背景色(高度100px),然后文本流也是自上而下。那么这个背景色我们是不是可以设置z-index: 0;然后文本流该咋写就咋写,然后是默认覆盖在背景上面的
。
🚩js
js技巧
Math对象
Math.random随机数
基础用法(返回一个浮点数,介于0(包括)和1(不包括)之间。[0, 1))
Math.random()
最小值~最大值区间的随机数
function getRandom(min, max) {
const random = Math.floor(Math.random() * (max - min + 1)) + min;
console.log(random);
}
getRandom(1, 5)
⭐️深浅拷贝
浅拷贝(拷贝的是地址,只能修改第1层)
实战一下
↓↓↓拷贝对象↓↓↓
const obj = {
name: '张三',
age: 18
};
// 1、展开运算符
const o = {
...obj,
age: 21
};
// 2、Object.assgin()
Object.assgin(o, obj);
o.age = 21;
↓↓↓拷贝数组↓↓↓
- 扩展运算符;
- slice()、map()等数组方法;
- forEach() + push()方法;
- 手动循环赋值。
直接赋值和浅拷贝的区别?
- 直接赋值:只要是对象,都会互相影响,因为是直接拷贝对象栈里面的地址。
- 浅拷贝:如果是
一层对象,不互相影响
,如果出现多层对象拷贝还会相互影响。
浅拷贝怎么理解?
拷贝对象之后,里面的属性值是简单数据类型直接拷贝值,如果是引用数据类型则拷贝的是地址。
深拷贝
- 递归(函数内部自己调用自己;容易"栈溢出"错误(stack overflow),所以必须要加退出条件return);
// 1、普通拷贝没问题直接复制就行;2、如果遇到数组,再次调用递归函数;3、如果遇到对象,再次调用递归函数;4、先数组再对象。
function deepCopy(newObj, oldObj) {
for (let key in oldObj) {
// 先写Array,在写Object。因为数组一定属于Object,Object不一定属于数组
if (oldObj[key] instanceof Array) {
newObj[key] = [];
deepCopy(newObj[key], oldObj[key]);
}
else if (oldObj[key] instanceof Object) {
newObj[key] = {};
deepCopy(newObj[key], oldObj[key]);
}
else {
newObj[key] = oldObj[key];
}
}
}
const obj1 = {
name: '张三',
age: 18,
habit: ['王者荣耀', '吃鸡'],
family: {
baby: '小张三'
},
address: null,
phone: undefined
}
const obj2 = {};
deepCopy(obj2, obj1);
// 这种也行,ai写的代码更简洁。总之代码初衷是可读性高,自己看哪种要好吧~
function deepCopy(newObj, oldObj) {
for (let key in oldObj) {
if (oldObj.hasOwnProperty(key)) {
if (oldObj[key] && typeof oldObj[key] === 'object') {
newObj[key] = oldObj[key].constructor === Array ? [] : {};
deepCopy(newObj[key], oldObj[key]);
} else {
newObj[key] = oldObj[key];
}
}
}
}
- lodash官网的cloneDeep方法;
第三方JavaScript 实用工具库: lodash官网
里面有_.cloneDeep
方法,直接按照文档引用就行。 - JSON.parse(JSON.stringify())
const obj2 = JSON.parse(JSON.stringify(obj1));
异常处理
throw关键字
- 抛出异常时使用
- 会终止程序
- 经常和Error对象一起使用
throw '抛出错误';
throw new Error('抛出错误');
try…catch…
try {
obj.name = '张三';
}
catch {
throw new Error('try里面的代码不对,obj为undefined,找不到该name');
}
finally {
console.log('不管try里面的代码对不对,都会走我这儿');
}
⭐️call、apply、bind
具体语法请去mdn官网查看
call(调用函数并可以传递参数)
const obj = {
name: '张三'
}
function fn(x, y) {
console.log(this);
console.log(x + y);
}
fn(); // this指向window
fn.call(obj, 1, 2); // this指向obj
apply(经常跟数组有关系)
和call的第一个参数都是this指向,但是apply第二个参数传递必须得是数组
。
const obj = {
name: '张三'
}
function fn(x, y) {
console.log(this);
console.log(x + y);
}
fn(); // this指向window
fn.call(obj, [1, 2]); // this指向obj
// 求数组最大值
console.log(Math.max.apply(null, arr));
⭐️bind(不调用函数,还想改变this指向,就用bind)
const obj = {
name: '张三'
}
function fn(x, y) {
console.log(this);
console.log(x + y);
}
fn(); // this指向window
const fnBind = fn.bind(obj, 1, 2); // this指向obj
fnBind(); // bind会返回一个新的函数,参数跟apply一样
总结:
1、call和apply会调用函数,改变函数内部的this指向,只不过apply第二个参数传递必须得是数组
;
2、bind不会调用函数,可以改变函数内部this指向。call和bind参数一样,都是call/bind(thisArg, arg1, arg2, /* …, */ argN)
,只不过bind不修改原数组会return出一个新数组
(我们就修改这个新数组里面的this指向咯)
发送短信小案例(在不使用_that,箭头函数,全局变量的情况下,只用bind来实现功能)
<button>发送短信</button>
document.querySelector('button').addEventListener('click', function() {
this.disabled = true;
setTimeout(function() {
this.disabled = false;
}.bind(this), 2000)
})
⭐️防抖和节流
防抖函数
function mydebounce(fn, t) {
let timer;
return function() {
timer && clearTimeout(timer);
timer = setTimeout(() => {
fn();
}, t);
}
}
节流函数
注意事项:定时器里面不能清除定时器,因为定时器还在运作,可以手动赋空进行覆盖
function mythrottle(fn, t) {
let timer;
return function() {
if (!timer) {
timer = setTimeout(() => {
fn();
console.log(timer);
timer = null;
console.log(timer);
}, t)
}
}
}
小案例
<button>点击</button>
let num = 0;
const btn = document.querySelector('button');
btn?.addEventListener('click', mydebounce(() => {
btn.innerHTML = `第${num++}次`;
}, 500))
![](https://img-blog.csdnimg.cn/img_convert/044c03b7d70aa942167bb030df6234f8.gif)