目录
- 一、如何理解HTML语义化
- 二、如何清除浮动(至少写两种)
- 三、触发bfc的方式(至少写三种)
- 四、写出元素水平居中与垂直居中(分内联元素与块级元素)
- 五、描述一下如何深度拷贝一个数组或对象
- 六、写出以下代码输出的值
- 七、修改第六个问题的代码,且不改变setTimeout与console代码的位置,使得输出结果值为0 - >1 - >2 - > 3 - >4 - > 5
- 八、解释一下事件委托的原理
- 九、描述一下闭包与使用场景
- 十、多个标签页之间通信有哪几种方式?
- 十一、有没有使用哪一些构建工具?简单描述一下前端模块化
- 十二、有使用过vue、react、angular数据驱动框架吗?描述一下他们的区别与组件化的理解
- 十三、简单描述一下es6+有什么新特性?
- 十四、在之前的工作中,前后端的开发模式有哪些?
一、如何理解HTML语义化
1、概念
HTML语义化指的是在书写html结构的时候,要使用有一定语义的标签表示和标记。
2、使用语义化的优点
代码结构清晰,有利于搜索引擎优化(SEO)。
3、常见语义化标签
header:定义文档的页眉(头部);
nav:定义导航链接的部分;
article:定义文章内容;
section:定义文档中的节(section、区段);
aside:定义其所处内容之外的内容(侧边);
footer:定义文档或节的页脚(底部)
二、如何清除浮动(至少写两种)
当子元素设置了浮动而父元素没有设置高度的时候,就会造成高度塌陷,因此需要对其清除浮动。
1、额外标签法
在浮动元素末尾添加一个空标签,并设置clear:both;样式
<div class="contain">
<div class="box1">盒子一</div>
<div class="box2">盒子二</div>
<div class="clear" style="clear: both;"></div>
</div>
2、触发bfc,给父元素添加overflow:hidden;
<div class="contain" style="overflow:hidden;">
<div class="box1">盒子一</div>
<div class="box2">盒子二</div>
</div>
3、伪元素:after
<div class="contain">
<div class="box1">盒子一</div>
<div class="box2">盒子二</div>
</div>
.contain:after{/*伪元素是行内元素 正常浏览器清除浮动方法*/
content: "";
display: block;
height: 0;
clear:both;
visibility: hidden;
}
.contain{
*zoom: 1;/*ie6清除浮动的方式 *号只有IE6-IE7执行,其他浏览器不执行*/
}
三、触发bfc的方式(至少写三种)
1、浮动元素
float除了none以外的值(left(左浮动)、right(右浮动)、inherit(继承父元素浮动))
2、绝对定位元素
position为absolute或fixed
3、display为以下其中之一的值
inline-block、table-cell、table-caption
4、overflow
overflow除了visible以外的值(hidden、auto)
四、写出元素水平居中与垂直居中(分内联元素与块级元素)
1、内联元素
水平居中:父元素设置text-align:center;
垂直居中:父元素设置line-height与height值相同
2、块级元素
水平居中: 自身元素添加margin: 0 auto;
垂直水平居中:
1、父元素:position:relative; 子元素:position:absolute;left:50%;right:50%;transform:translate(-50%,-50%);
2、父元素:display:flex;justify-content:center;align-item:center;
五、描述一下如何深度拷贝一个数组或对象
1、JSON方法
JSON.parse(JSON.stringify(obj))
2、递归
function deepCopyObj(obj) {
if (typeof obj == "object") {
let newObj
if (Object.prototype.toString.call(obj) == "[object Array]") {
console.log("是数组");
newObj = []
obj.forEach((element,index) => {
newObj[index] = deepCopyObj(element)
});
return newObj
} else if (Object.prototype.toString.call(obj) == "[object Object]") {
console.log("是对象");
newObj = {}
for(let j in obj) {
newObj[j] = deepCopyObj(obj[j])
}
return newObj
} else {
console.log("都不是");
return obj
}
} else {
return obj;
}
}
let obj = {
a: 1,
b: {
c: 2,
d: 3,
},
};
const obj1 = deepCopyObj(obj);
console.log(obj1);
let arr1 = [1,2,3,[2,5,6,4],{a:22}]
const arr2 = deepCopyObj(arr1);
console.log(arr2);
六、写出以下代码输出的值
for(var i = 0;i<5;i++) {
setTimeout(()=> {
console.log(new Date(),i)
},1000)
}
console.log(new Date(),i)
输出结果值如下:
七、修改第六个问题的代码,且不改变setTimeout与console代码的位置,使得输出结果值为0 - >1 - >2 - > 3 - >4 - > 5
for(var i = 0;i<5;i++) {
let a = i
setTimeout(()=> {
i = a
console.log(new Date(),i)
},1000)
}
setTimeout(()=> {
i++
console.log(new Date(),i)
},1000)
for (var i = 0; i < 5; i++) {
(function (i) {
setTimeout(() => {
console.log(new Date(), i);
}, 1000);
})(i);
}
setTimeout(() => {
console.log(new Date(), i);
}, 1000);
输出结果值如下:
八、解释一下事件委托的原理
事件委托也称为”事件代理“,指的是原本需要绑定在子元素的响应事件委托给父元素,让父元素担当事件监听的职务。
事件代理的原理是DOM元素的事件冒泡。即一个元素的事件触发后,会依次一级一级往上调用父级元素的同名事件,直到window(注:IE8和之前的浏览器只到document)
九、描述一下闭包与使用场景
概念:函数外部无法访问函数内部的局部变量,但函数内部的函数可以访问本函数内的局部变量,故通过闭包实现函数外部访问函数内部局部变量。但容易造成内存泄漏,应当谨慎使用。
使用场景:
1、防抖
function debounce (fn, delay = 1000) {
let time = null
return function () {
// 获取当前this
let that = this
// 判断是否已经存在,如果存在直接清除
if (time) {
clearTimeout(time)
}
time = setTimeout(() => {
// 使fn中this,执行当前调用者,并传入参数
fn.apply(that, arguments)
}, delay)
}
}
function logger(){
console.log('test')
}
btn.addEventListener('click',debounce(logger, 1000))
2、节流
function throttle (fn, delay = 1000) {
let time = null;
return function () {
let that = this;
// 如果已经存在定时器了,则不做处理
if (!time) {
time = setTimeout(() => {
fn.apply(that, arguments);
// 完结时,将time改为null,清除定时器
time = null;
}, delay);
}
};
}
十、多个标签页之间通信有哪几种方式?
1、websocket协议
理论上可实现任何数据共享跨域共享,但是会增加服务器的压力
2、postMessage方法
PostMessage 是 html5 新引进的一个可跨源通信 api。通过这个 api,让主页面和任意 frame 类页面或 window.open 打开的页面进行双向通信。
3、localStorage
注意:只能监听非己页面且跨域不共享
十一、有没有使用哪一些构建工具?简单描述一下前端模块化
webpack、vite、gulp
模块化:是一种代码组织方式,一个模块就是一个实现特定功能的文件,它通过把我们的复杂代码按照功能的不同,划分为不同的模块单独维护的这种方式,去提高我们的开发效率,降低维护成本。
十二、有使用过vue、react、angular数据驱动框架吗?描述一下他们的区别与组件化的理解
vue
区别:
组件化:为了让页面中的各个部分可以被复用,以减少重复的代码。另一方面,也可以更好地使团队分工协作,让不同的人负责编写不同的组件。
十三、简单描述一下es6+有什么新特性?
1. Symbol
基本数据类型:Symbol,每一个被创建的symbol类型值都是独一无二的,Symbol('test') == Symbol('test')返回值为false
2、let和const
声明变量:let、const块级作用域
3、解构赋值
解构赋值是对赋值运算符的扩展。它是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。
所有可枚举(iterable)的对象都可以使用解构赋值,例如数组,字符串对象,以及ES6新增的Map和Set类型。
例:let [a,b,c] = [1,2,3]
4、Map和Set
Map对象不同与普通对象,是可迭代对象,Set对象具有唯一性的特点,可用于数组去重。
5、扩展运算符…
const obj = { a: 1, c: 2 };
const obj1 = { a: 3, b: 3 };
let newObj ={...obj,...obj1}
console.log(newObj); // { a: 3, b: 3 , c:2}
6、箭头函数
()=> {
console.log(1)
}
7、promise/proxy
promise:把异步的操作用同步的流程表达出来,解决了回调地狱的问题
proxy:可以直接监听整个对象而非属性,可以监听数组的变化
等等等。。。
十四、在之前的工作中,前后端的开发模式有哪些?
前后端分离