手撕面包
十三、手写new
十二、柯里化函数
溯源历史
这个思想可以追溯到19世纪数学家Gottlob Frege,但组合逻辑创始人 Haskell Curry对其进行系统化研究和发展,所以用了他的名字 Curry 命名。
函数柯里化从数学引入计算机领域,主要原因是函数式编程范式的兴起、λ演算的理论基础、提供了更灵活的函数组合方式:

过程式语言如C,因为设计哲学的原因,函数在这里不是“一等公民”,所以不支持柯里化。
概念与应用
概念:一种将多参数函数转化为一系列单参数函数的技术。每个函数接受一个参数并返回接受下一个参数的函数,直到所有参数都收集完毕才执行函数。
应用:参数复用(事件处理、配置函数等场景)、延迟执行、函数组合。link,搜'应用场景(前端特定)'
经典面试题
实现技术点:
- 基于闭包:利用JS的闭包特性保存中间状态
- 延迟执行:参数未收集完成时不执行实际计算
- 函数组合友好:便于创建可复用的函数片段
经典面试题 题解:
function curryFn(fn) {
if(typeof fn !== 'function'){
throw new TypeError('curry requires a function')
}
return function curried(...args){
// 如果传入的参数数量大于等于 原函数 需要的参数数量,直接调用原函数
if(args.length >= fn.length){
return fn.apply(this,args)
}
// 否则返回一个新函数,继续接收剩余参数
return function (...nextArgs) {
return curried.apply(this,args.concat(nextArgs))
}
}
}
十一、实现九宫格布局
考察CSS的布局和运用的理解能力,包括Flexbox、Grid、float、table.应用场景:电商产品图展示,功能入口网络、游戏界面、数据展示等。衍生问题:
- Flexbox vs Grid 各自的优缺点?
- 如何选择适合的布局方案?
- 不同方案的浏览器兼容性如何?
Flex box适合一维布局(单行或单列),Grid适合二维布局;实际开发中可能会结合使用,移动端采用flex,大屏设备使用grid.这样既能保证浏览器的兼容性,又能保证现代浏览器的强大功能。
Flexbox
.container{
display:flex;
flex-wrap:wrap;
width:300px;
height:300px;
}
.item{
width: 33.33%;
height: 33.33%;
box-sizing: border-box;
border: 1px solid #ccc;
}
Grid 布局(现代推荐)
.container{
display: grid;
/* repeat是重复函数,表示重复3次,fr 单位表示网格容器中可用空间的一部分。
1fr表示意味着网格容器被分为3列,每列宽度相等,各占可用空间的1/3。 */
grid-template-columns: repeat(3,1fr);
grid-template-rows: repeat(3,1fr);
width: 300px;
height: 300px;
gap: 1px;
background: #ccc;
}
.item{
background: purple
}
float(传统方案)
.container{
width: 300px;
height: 300px;
background: #ccc;
overflow: hidden;
}
.item{
background: purple;
float: left;
width: 33.33%;
height: 33.33%;
/* 浮动布局中元素要加上box-sizing:border-box的写法 因为是为了解决盒模型计算的问题
浮动布局依赖精确的宽度计算,百分比宽度配合 border-box 可以确保布局准确。 */
box-sizing: border-box;
border: 1px solid #ccc;
}
table布局不做解释,它的语义不符合主流写法。
十、用css实现三角
标准答案有八种三角形实现,但我觉得只需要知道核心原理、实现能力(写出1-2种三角形)、扩展思维(举一反三推出其他三角形实现)就可以了。
css实现
<div class="triangle"></div>
<style>
.triangle{
width:0;
height:0;
/* 向上的三角形,代码里就写下,反过来的,朝向左右也同理 */
border-bottom:50px solid #333;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
/* 向下的三角形 */
border-top:50px solid #333;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
}
</style>
clip-path方法
clip-path是CSS3的属性,用于裁剪元素的显示区域,polygon()用于定义多边形的坐标;坐标点可以按顺时针或逆时针顺序排列,但必须连续且有序;
%是相对于元素自身的宽高,当然也可以用px表示。
.triangle{
width:100px;
height:100px;
background:#333;
clip-path:polygon(100% 0,50% 100%,0 0)
}
canvas实现
<canvas id="myCanvas" width="100" height="100"></canvas>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// 方法1:路径绘制
ctx.beginPath();
ctx.moveTo(50, 0); // 起点:顶部中点
ctx.lineTo(0, 100); // 左下角
ctx.lineTo(100, 100); // 右下角
ctx.closePath(); // 自动回到起点
ctx.fillStyle = '#333';
ctx.fill();
// 方法2:更简洁的写法
ctx.beginPath();
ctx.moveTo(50, 0);
ctx.lineTo(0, 100);
ctx.lineTo(100, 100);
ctx.fill(); // 自动闭合路径并填充
</script>
九、文字溢出
文字溢出与文本溢出
- 文字溢出 重点是单个字符的视觉表现和排版
先展示单行方案,强调这是最基础最重要的; 再展示多行方案,说明WebKit限制和替代方案; 重点体现对CSS基础属性的熟练掌握;
- 文本溢出 重点是段落内容的布局和结构处理
重点展示兼容性更好的定位方案; 详细说明伪元素的实现原理; 讨论背景色匹配、行高计算等细节问题; 体现解决实际问题的能力;
单行文字实现
.text{
text-overflow: ellipsis;/*ellipsis 省略*/
overflow: hidden ;
white-space: nowrap;/*nowrap 换行*/
}
多行文字实现
即第八、旧版弹盒法
八、文本溢出
前端开发中使用场景:内容列表展示、卡片布局。有两种方式,如果对兼容性要求高,需要支持所有现代浏览器,使用定位伪元素遮盖;若用户使用的是Chrome或Safari,使用旧版弹盒法。
定位伪元素遮盖
.father{/*父元素*/
postion:relative;/*子绝父相 给伪元素定位*/
overflow:hidden;
text-align:justify;
line-height:20px;
}
.father::after{
position:absolute;
right:0;
bottom:0;
content:'...';/*插入省略文本*/
width:1em;/*为了遮盖时正好遮住原来一个字的大小*/
background-color:'';/*设置和父元素背景相同的颜色*/
}
伪元素vs伪类
伪元素:创建不在文档树中的虚拟元素,::
伪类:选择已有元素的状态,:
旧版弹性盒法
.box{
display: -webkit-box;
/* 弹性盒子元素垂直排列 */
-webkit-box-orient: vertical;
/* 控制要显示的行数 */
-webkit-line-clamp: 3;
overflow: hidden;
}
七、三栏布局
解释
将页面水平分为三份,表现形式:左右固定中间自适应(常见,经典圣杯布局、双飞翼布局)、左右自适应中间固定、三个都自适应(比例一般1:2:1)、一个固定两个自适应(少见)
实现方式
绝对定位不推荐,脱离文档流
relative:不脱离文档流,不影响其他元素布局。absolute:脱离文档流,根据父元素或根元素定位。
<div class="container">
<div class="main">中间自适应</div>
<div class="left">左侧固定</div>
<div class="right">右侧固定</div>
</div>
<style>
.contain{
padding: 0 200px;
overflow: hidden;
}
.main,.left,.right{
float: left;
position: relative;
min-height: 300px;
}
.main{
background-color: pink;
width: 100%;
}
.left{
background-color: plum;
margin-left: -100%;/* 移动到上一行的最左侧 */
right: 200px;/* 相对定位调整到正确位置 */
width: 200px;
}
.right{
background-color: aquamarine;
width: 200px;
/* 为什么不用margin-right?
因为所有栏都设置了float:left 元素从左到右排列 一定要用margin-left 移动到上一行的最右侧*/
margin-left: -200px;
left: 200px;/* 相对定位调整到正确位置 */
}
</style>
<div class="double-wing">
<div class="main-wrapper">
<div class="main">中间内容(自适应)</div>
</div>
<div class="left">左侧边栏(固定200px)</div>
<div class="right">右侧边栏(固定200px)</div>
</div>
<style>
.double-wing {
overflow: hidden;
min-height: 300px;
}
.main-wrapper, .left, .right {
float: left;
min-height: 300px;
}
.main-wrapper {
width: 100%;
background: pink;
}
.main {
margin: 0 200px;/* 主要内容区域的内边距 */
height: 100%;
background: plum;
}
.left {
width: 200px;
margin-left: -100%;/* 移动到第一行最左边 */
background: beige;
}
.right {
width: 200px;
margin-left: -200px;/* 移动到第一行最右边 */
background: beige;
}
</style>
<div class="flex-container">
<div class="left">左侧边栏(固定200px)</div>
<div class="main">中间内容(自适应)</div>
<div class="right">右侧边栏(固定200px)</div>
</div>
<style>
.flex-container{
display: flex;
min-height: 300px;
}
.left{
width: 200px;
order: 1;/*控制显示顺序*/
background: plum;
}
.main{
flex: 1;/*占据剩余所有空间*/
order: 2;
background: pink;
}
.right{
width: 200px;
order: 3;
background: plum;
}
</style>
<div class="grid-container">
<div class="left">左侧边栏(固定200px)</div>
<div class="main">中间内容(自适应)</div>
<div class="right">右侧边栏(固定200px)</div>
</div>
<style>
.grid-container{
display: grid;
grid-template-columns: 200px 1fr 200px; /* 左右固定,中间自适应 */
min-height: 300px;
gap: 0; /* 可选:去掉间距 */
}
.left{
background: plum;
}
.main{
background: pink;
}
.right{
background: plum;
}
</style>
圣杯和双飞翼的名字由来
- 圣杯:西方文化中象征着"神圣的追求目标"(耶稣晚餐用过的杯子 比作美好),这个布局在当时(2006年左右)被认为是CSS布局的"圣杯"——一个难以实现但非常理想的三栏布局目标。
- 双飞翼:由淘宝UED团队提出,名字来源于"双翼",比喻中间内容区域像鸟的身体,左右两侧像翅膀一样展开。
- 两者都是三栏布局,且最后呈现的视觉效果相同,但代码实现思路不同;
- 双飞翼是圣杯的优化版本,解决了浏览器兼容问题;圣杯的html结构更简洁,双飞翼多一层包裹。
- 注意:圣杯布局和双飞翼布局的中间栏div都是在html结构中先写的,这样写浏览器会优先解析展示中间内容,利于SEO.

六、两栏布局
解释
两栏布局是一种布局现象,并不是css种规定的专业名词,但行业通用。
最常见的是左侧固定、右侧自适应;除此之外,还有右侧固定、左侧自适应;两侧都自适应
<div class="container">
<div class="left">左边浮动元素</div>
<div class="right">右边普通元素</div>
</div>
实现方式
掌握浮动和Flex就足够应对大多数情况。
Grid布局比较新颖(语义化);绝对定位:不推荐,影响文档流;表格布局:display: table 已过时
/* 1.父元素加BFC,固定部分浮动并给出宽高,自适应部分使用margin-方向来固定 */
.container {
border: 3px solid red; /* 用红色边框标识父容器范围 */
overflow: hidden;
}
.left {
float: left;
width: 200px;
background-color: gray;
height: 400px;
}
.right {
/* 注意:这里没有 margin-left */
margin-left: 200px;
background-color: lightgray;
height: 200px;
}
/* 2.父元素flex,固定部分给出宽度,自适应部分用flex:1的属性拉满剩余空间 */
.container {
border: 3px solid red; /* 用红色边框标识父容器范围 */
display: flex;
}
.left {
width: 200px;
background-color: gray;
height: 400px;
}
.right {
flex: 1;/* 自适应部分占据剩余空间 */
background-color: lightgray;
height: 200px;
}
/* 3.Grid布局 新颖且语义化; */
.container {
border: 3px solid red; /* 用红色边框标识父容器范围 */
display: grid;
grid-template-columns: 250px 1fr;/*第一列宽度250px 第二列宽度剩余空间的一部分*/
grid-template-areas: "sidebar main";/*定义子元素语义化属性*/
}
.left {
grid-area: sidebar;
background: #f0f0f0;
background-color: gray;
height: 400px;
}
.right {
grid-area: main;
background-color: lightgray;
height: 200px;
}
