【html、css、js三剑客踩坑点】(持续迭代)

🚩前端必备文档记录

注:知识无价,白嫖的知识更应珍惜。网上免费教材众多,学会筛选更利于成长!

类型网站用途网站链接
教材类mdn(前端的百科全书)https://developer.mozilla.org/zh-CN/
Javascript.infohttps://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;

文本省略

单行文本省略

white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;

多行文本省略

overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;		// 文本显示几行

层叠上下文 z-index

mdn官网对z-index层叠上下文的介绍

不设置z-index值,默认值为auto,啥也没有;
设置z-index值哪怕值为-1、0也会创建层叠上下文
例如:有3个子盒子,那这3个子盒子的z-index只在设置了层叠上下文的父盒子里面生效

应用场景:例如有个自上而下的背景色(高度100px),然后文本流也是自上而下。那么这个背景色我们是不是可以设置z-index: 0;然后文本流该咋写就咋写,然后是默认覆盖在背景上面的

🚩js

js技巧

Math对象

Math.random随机数

官文:mdn的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;

↓↓↓拷贝数组↓↓↓

  1. 扩展运算符;
  2. slice()、map()等数组方法;
  3. forEach() + push()方法;
  4. 手动循环赋值。
直接赋值和浅拷贝的区别?
  • 直接赋值:只要是对象,都会互相影响,因为是直接拷贝对象栈里面的地址。
  • 浅拷贝:如果是一层对象,不互相影响,如果出现多层对象拷贝还会相互影响。
浅拷贝怎么理解?

拷贝对象之后,里面的属性值是简单数据类型直接拷贝值,如果是引用数据类型则拷贝的是地址

深拷贝
  1. 递归(函数内部自己调用自己;容易"栈溢出"错误(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];
            }
        }
    }
}
  1. lodash官网的cloneDeep方法;
    第三方JavaScript 实用工具库: lodash官网
    里面有_.cloneDeep 方法,直接按照文档引用就行。
  2. 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))
  • 29
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值