闭包是指函数能够记住并访问它的词法作用域,即使这个函数在词法作用域之外执行。
应用场景:
function createCounter() {
let count = 0;
return function() {
count++;
return count;
};
}
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
事件循环是JavaScript的一种运行机制,它允许非阻塞的异步代码执行。事件循环会不断地检查调用栈是否为空,如果为空,则检查微任务队列,然后执行所有微任务,接着再检查宏任务队列,执行一个宏任务。
宏任务和微任务的区别:
setTimeout
、setInterval
等。Promise
的回调、MutationObserver
等。深拷贝是指复制一个对象及其所有嵌套对象,使得新对象与原对象完全独立。
/**
* 深度拷贝函数,用于复制一个对象及其所有嵌套对象,使得新对象与原对象完全独立。
* @param {any} obj - 需要被深拷贝的对象。
* @returns {any} - 返回深拷贝后的新对象。
*/
function deepCopy(obj) {
// 如果传入的是null、undefined、基本数据类型(string, number, boolean等)或者函数,直接返回,因为这些类型不需要深拷贝。
if (obj === null || typeof obj !== 'object' || typeof obj === 'function') {
return obj;
}
// 处理数组
if (Array.isArray(obj)) {
// 使用map方法创建一个新数组,数组的每个元素都是递归调用deepCopy的结果。
return obj.map(item => deepCopy(item));
}
// 处理普通对象
const copy = {}; // 创建一个空对象作为新对象的容器。
for (const key in obj) {
// 使用hasOwnProperty方法确保只拷贝对象自身的属性,不包括从原型链上继承的属性。
if (obj.hasOwnProperty(key)) {
// 递归调用deepCopy,将每个属性的值深拷贝到新对象中。
copy[key] = deepCopy(obj[key]);
}
}
// 返回深拷贝后的新对象。
return copy;
}
this
的值,后面参数逐个传递。this
的值,第二个参数是一个数组或类数组对象,其中的数组元素将作为单独的参数传给函数。bind()
被调用时,这个新函数的this
被指定为bind()
的第一个参数,其余参数将作为新函数运行时的初始参数,供调用时使用。原型链是JavaScript中实现继承的一种机制。每个对象都有一个原型对象,对象从其原型对象继承属性和方法。如果对象自身没有某个属性或方法,JavaScript引擎会沿着原型链向上查找,直到找到为止。
实现继承:
function Parent(name) {
this.name = name;
this.colors = ['red', 'blue', 'green'];
}
Parent.prototype.getName = function() {
return this.name;
};
function Child(name, age) {
Parent.call(this, name); // 构造器继承
this.age = age;
}
Child.prototype = new Parent(); // 原型链继承
Child.prototype.constructor = Child;
Child.prototype.getAge = function() {
return this.age;
};
const child = new Child('Alice', 10);
console.log(child.getName()); // Alice
console.log(child.getAge()); // 10
Flexbox
.parent {
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
height: 100vh; /* 假设父容器高度为视口高度 */
}
.child {
/* 子元素样式 */
}
Grid
.parent {
display: grid;
place-items: center; /* 同时水平和垂直居中 */
height: 100vh; /* 假设父容器高度为视口高度 */
}
.child {
/* 子元素样式 */
}
使用绝对定位和变换
.parent {
position: relative;
height: 100vh; /* 假设父容器高度为视口高度 */
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
BFC(Block Formatting Context) 是一个独立的渲染区域,只有属于同一个 BFC 的元素才会相互影响。BFC 的触发条件包括:
)float
不是 none
)position
是 absolute
或 fixed
)display
为 inline-block
, flex
, inline-flex
, grid
, inline-grid
, table-cell
, table-caption
, flow-root
overflow
不是 visible
contain
为 layout
, content
, 或 paint
应用场景:
CSS 选择器的优先级基于选择器的类型,计算规则如下:
style="..."
。#id
,优先级为 0,1,0,0
。.class
, [attr=value]
, :hover
,优先级为 0,0,1,0
。div
, p
, ::before
,优先级为 0,0,0,1
。*
,优先级最低,为 0,0,0,0
。优先级计算时,按 a,b,c,d
的顺序比较,a
的值越大,优先级越高;如果 a
相同,则比较 b
,以此类推。
!important > 内联>id>类>标签>通配符
通过设置一个元素的宽度和高度为 0,并使用边框来创建三角形。例如,一个向下的三角形可以这样实现:
.triangle {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-top: 100px solid black;
}
正三角,border-bottom:100px solid black;
Flexbox 是一种用于在容器中分布、对齐和排列子元素的一维布局方法。
常用属性:
display: flex;
:将容器设为 Flex 容器。flex-direction: row | row-reverse | column | column-reverse;
:定义主轴方向。justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
:定义项目在主轴上的对齐方式。align-items: flex-start | flex-end | center | baseline | stretch;
:定义项目在交叉轴上的对齐方式。flex-wrap: nowrap | wrap | wrap-reverse;
:定义项目是否换行。align-content: flex-start | flex-end | center | space-between | space-around | stretch;
:多行时的对齐方式。order: number;
:定义项目的排列顺序。flex-grow: number;
:定义项目的放大比例。flex-shrink: number;
:定义项目的缩小比例。flex-basis: length | auto;
:定义在分配多余空间之前,项目的默认大小。align-self: auto | flex-start | flex-end | center | baseline | stretch;
:允许单个项目在交叉轴上有不同的对齐方式,覆盖 align-items
。Object.defineProperty
方法给对象的属性添加getter和setter,以实现响应式。但这种方法有一些局限性,比如无法监听属性的添加和删除,也无法监听数组的变化(虽然Vue做了特殊处理)。Proxy
对象来创建一个响应式代理。Proxy
不仅可以监听属性的读取和设置,还可以监听属性的添加、删除以及数组的变化,提供了更全面的响应式能力。Proxy
解决了Object.defineProperty
无法监听属性添加、删除和数组变化的局限。Proxy
的拦截范围更广,可以在一个地方集中处理各种操作,可能有助于优化性能。Proxy
可以减少一些Vue 2中为了处理特殊情况而增加的复杂代码。$el
属性目前不可见。created
阶段可以访问data
和methods
,因为此时它们已经被初始化。onMounted
、onUpdated
、onUnmounted
等函数来模拟Vue 2中的生命周期钩子。这些函数是Vue 3提供的Composition API的一部分,用于在组件的不同生命周期阶段执行代码。props
。$emit
触发事件。provide
和inject
来在祖先组件和后代组件之间传递数据。data
用于存储数据,methods
用于定义方法。setup
函数和ref
、reactive
等响应式API,可以将相关的逻辑组合在一起,形成一个可复用的模块。这使得代码更加模块化和易于维护。setup
函数中直接访问2025/02/17