前端面试题(一)

一、如何理解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:可以直接监听整个对象而非属性,可以监听数组的变化

等等等。。。

十四、在之前的工作中,前后端的开发模式有哪些?

前后端分离
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值