一、css
1.相对定位和绝对定位(2022/4/14)
relative:定位是相对于自身所在位置定位偏移。
absolute:定位是相对于离元素最近的设置了绝对或相对定位的父元素决定的,如果没有父元素设置绝对或相对定位,则元素相对于根元素即html元素定位。
总结:父相子绝
2.背景图片(2022/4/21)
图片叠加在白底上
background: no-repeat white url('../../assets/img/bg.png');
background-size: 100%;
3.限制文本长度显示省略号(2022/4/21)
word-break: break-all;
/* break-all(允许在单词内换行。) */
text-overflow: ellipsis;
/* 超出部分省略号 */
overflow: hidden;
display: -webkit-box;
/** 对象作为伸缩盒子模型显示 **/
-webkit-box-orient: vertical;
/** 设置或检索伸缩盒对象的子元素的排列方式 **/
-webkit-line-clamp: 2;
/** 显示的行数 **/
4.opacity透明度覆盖子元素(2022/4/21)
针对子元素继承父元素的透明度(opacity)的情况,
.box{background: #000;opacity:0.7}
即使给子元素设置opacity:1,也是在父元素的基础上计算的,即1*0.7
解决办法:
1.使用rgba:
background-color:rgba(0,0,0,0.7)
2.改为兄弟元素,再用定位position:absolute;
5.js修改css变量(2022/4/21)
css中
top:var(--traceNavTop);
js view中
<View style={{"--traceNavTop":15}} />
6.渐变(2022/4/21)
从左到右渐变,第一个值为方向
background: linear-gradient(left,#B9FFB7,#07BA6F)!important;
7.不影响布局扩大按钮的点击区域(2022/4/24)
在保持点击的按钮的本身的大小不变,且不会影响页面的其他位置的布局的情况下扩大可点击区域,可通过css3的伪类来实现
.btn{
&::after{
content: '';
position: absolute;
top: -10px;
left: -10px;
right: -10px;
bottom: -10px;
}
}
二、js
1.js数据类型(2022/4/14)
JavaScript有八种内置类型
空值(null)
未定义(undefined)
布尔值(boolean)
数字(number)
字符串(string)
对象 (object) //非基本类型
符号(symbol, ES6中新增)
大整数(BigInt, ES2020 引入)
typeof null // 'object'
typeof undefined; // "undefined"
typeof false; // "boolean"
typeof 1; // "number"
typeof '1'; // "string"
typeof {}; // "object"
typeof []; // "object"
typeof new Date(); // "object"
typeof Symbol(); // "Symbol"
typeof 123n // 'bigint'
2.== 与===的区别(2022/4/14)
===:相同类型的前提下比较值是否相等
==:只判断值,自动转换类型
3.深拷贝和浅拷贝(2022/4/14)
作用场景:变量赋值
知识点:除了引用型数据是存储在堆中的,其他类型都是存储在栈中的,而引用型的数据会在栈中保留一个指针,指向在堆中的位置
浅拷贝(引用拷贝):复制指向某个对象的指针,即引用地址,被赋值与赋值的变量指向同一内存,二者会相互影响。
//浅拷贝赋值
let a={
name:'张三',
age:27,
}
let b={};
//1.=赋值
b=a;
//2.for
for(var key in a) {
b[key] = a[key]
}
//3.ES6 assign
Object.assign(b,a)
b.name='李四'
console.log(a.name);//李四
console.log(b.name);//李四
深拷贝(值拷贝):只复制值,独立开辟内存空间,与原来的对象互不干扰。
//深拷贝赋值
//1.for循环(多层需递归)
function deepCopy(newObj, copyObj) {
for (var k in copyObj) {
if (copyObj[k] instanceof Array) {//先判断数组,数组类型的数据instanceof Object 也为true
newObj[k] = []; // 相当于如果是复杂数据类型则另外开辟空间存储 target[k]的属性值
deepCopy(newObj[k], copyObj[k]); // 将 copyObj[k] 的内容拷贝给 target[k]
} else if (copyObj[k] instanceof Object) {
newObj[k] = {};
deepCopy(targetObj[k], copyObj[k]);
} else {
newObj[k] = copyObj[k];
}
}
};
deepCopy(b,a)
//2.JSON
b=JSON.parse(JSON.stringify(a));
//3.es6 ...拓展符
b={...a}
//4.仅用于数组 slice(),截取数组,不影响原数组,产生一个新数组
b=a.slice()
//5.仅用于数组 concat(),连接数组,不改变原数组
b=[].concat(a)
b.name='李四'
console.log(a.name);//张三
console.log(b.name);//李四
4.防抖和节流(2022/4/14)
防抖:指在事件触发n秒后再执行回调,如果在n秒内再次被触发,则重新计算时间。通过增加定时器settimeout的方式来让代码延迟执行,只有当他停下来之后,才会继续执行,即一直触发一直不执行,只对最后一次进行操作。
主要应用场景有:
a、scroll事件滚动触发,
b、搜索框输入查询
c、表单验证
d、按钮提交事件
e、浏览器窗口缩放,resize事件
let timer: any = null
const debounce = (time:number) => {
timer=null;
timer = setTimeout(() => {
//事件执行
...
}, time)
}
调用:debounce (500)
节流:指如果持续触发某个事件,则每隔n秒执行一次。在我们规定的时间内,不管持续触发事件多少次,只进行一次操作。
主要应用场景:
a、DOM元素的拖拽功能实现
b、射击游戏类
c、计算鼠标移动的距离
d、监听scroll事件
let timer: any = null
const throttle = (time:number) => {
if (!timer) {
timer = setTimeout(() => {
//事件执行
...
timer = null
}, time)
}
}
调用:throttle (500)
5.词法作用域(Lexical Scopes)(2022/4/14)
词法作用域,就意味着函数被定义的时候,它的作用域就已经确定了,和拿到哪里执行没有关系,因此词法作用域也被称为 “静态作用域”。
var val = 1;
function foo1() {
console.log('val=',val);
}
function foo2() {
var val = 2;
foo1();
}
foo2();//val = 1
执行foo2中的foo1()时,引擎为了拿到这个变量就要去 foo1的上层作用域查询,此时 foo1的上层作用域是它定义时所在的全局作用域,而非是它调用时所在的foo2作用域。
6.闭包与内存泄漏(2022/4/14)
6.1闭包的形成与作用
在JavaScript中,在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量,则产生闭包。
形成闭包三要素:
- 外层函数包裹内层函数
- 内层函数引用外层函数的变量
- 外层函数返回内层函数
闭包的作用:保护数据的安全
- 保护函数的私有变量不受外部的干扰。形成不销毁的栈内存。
- 保存,把一些函数内的值保存下来。闭包可以实现方法和属性的私有化
let count = 100;//全局作用域,不安全
foo1() {
let count = 0; //函数全局作用域,私有变量,保护count
function foo2() {
count++; //函数内部作用域
return count;
}
return foo2; //返回函数
}
let result = this.foo1();//result即foo2(){},此时count值为0
console.log("foot1", this.foo1());//只执行foo1,返回foo2
console.log("foot1()", this.foo1()());//每次都会创建一个新的count,再执行foo2,因此调用多次结果仍为1
console.log("foot1()2", this.foo1()());
console.log("result1", result());//在count值为0的基础上,再执行foo2()==>1
console.log("result2", result());//在count值为1的基础上,再执行foo2()==>2
在这个示例中,我们定义了 foo1() 函数,它定义count变量初始值为0 ,并返回一个新的函数。返回的函数使用count+1,并返回count的值。
从本质上讲,foo1() 是一个函数工厂 — 他创建了将指定的值+1的函数。result则保存该函数的引用地址及count值。
虽然两次都是调用result(),但是使用的count的值不同。第一次调用时,count 为 0。而第二次调用时,count 则为 1。
6.2内存泄漏
内存泄露 是指当一块内存不再被应用程序使用的时候,由于某种原因,这块内存没有返还给操作系统或者内存池的现象。内存泄漏可能会导致应用程序卡顿或者崩溃。
闭包过度使用会导致性能问题。由于闭包笼统的说相当于函数套函数,在返回内部函数时,会把外部变量也打包进去 ,所以该变量不会被回收 ,也就造成了内存泄漏。因此需要在函数调用过后,对闭包进行释放,否则该变量会一直存在于内存中,而造成内存泄漏。
//闭包的释放
result = null // 释放对闭包的引用
console.log(result()) //Uncaught TypeError: result is not a function
其他可能造成内存泄漏的原因及解决方案:
- 全局变量的无意创建
"use strict";//使用严格模式,避免不经意间的全局变量泄露
function foo() {
b = 2;//未使用let、var、const
console.log(b);
}
foo(); // 2
console.log(b); // 2
- dom绑定的事件没有移除
window.addEventListener('resize', fn, false);
//页面卸载或dom元素移除时未注销绑定事件,在销毁阶段记得解绑相关事件
window.removeEventListener('resize', fn, false);
5.跨域(2022/8/10)
跨域:不同域之间相互请求资源。当协议、子域名、主域名、端口号中任意一个不相同时,都算作不同域。
这是因为JavaScript同源策略(源相同才能正常通信)的限制,a.com域名下的js无法操作b.com或是c.a.com域名下的对象。同时跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。