2021前端面试题总结

1.css

1.1. 使用css如何画出三角形

        //三角形实现方法1
		div{
			width: 0;
			height: 0;
			border: 20px solid transparent;
			border-bottom-color: red;
		}
		//三角形实现方法2
		div::before{
			display: block;
			content: '';
			width: 0;
			height: 0;
			border: 20px solid transparent;
			border-bottom-color: red;
		}
		//三角形实现方法3
		div::after{
			display: block;
			content: '';
			width: 0;
			height: 0;
			border: 20px solid transparent;
			border-bottom-color: red;
		}

1.2. 使用css如何让浮动元素上下,左右居中

        /* 浮动元素居中 */
		/* 子元素添加下面的样式 */
		.child{
			float: left;
			width: 80px;
			height: 80px;
			background-color: aqua;
			position: relative;
			left: 50%;
			top: 50%;
			margin-left: -40px;
			margin-top: -40px;
		}
		/* 父元素添加下面的样式 */
		.centerBox1{
			display: flex;
			flex-direction: row;
			align-items: center;
			justify-content: center;
		}

1.3. 什么是盒子模型

盒子模型分为两种: 一种是IE盒子模型,另一种是标准盒子模型(w3c标准),盒子模型由:内容(content)+内边距(padding)+边(border)+外边距(margin);

两种模型的不同之处:IE盒子模型content是由content+padding+border组成

                                    标准盒子模型的content就是单独的content。不包括border和padding。如下图:

1.4. 关于flex布局

 

1.5. css3有哪些新特性,新增的伪类有哪些

新增特性:

边框圆角:border-radius
边框图像:border-image
背景图:background-image
阴影:box-shadow
渐变:
    线性渐变:background:linear-gradient('方向','开始颜色',....,'结束颜色')
    径向渐变:background:radient-gradient(圆的类型 渐变的大小 at 渐变的位置, '开始颜色', ...,                     '结束颜色')

文本效果:
    word-break:定义如何换行。
    word-wrap:允许长的内容可以自动换行。
    text-overflow:指定当文本溢出包含它的元素,应该发生什么。
    text-shadow:文字阴影。

转换:transform
过度:transition
动画: animation
多栏布局:flex
媒体查询:@media

新增伪类(选择器):

:first-of-type 选择器匹配属于其父元素的特定类型的首个子元素的每个元素。
:last-of-type 选择器匹配属于其父元素的特定类型的最后一个子元素的每个元素。
:only-of-type 选择器匹配属于其父元素的特定类型的唯一子元素的每个元素。
:only-child 选择器匹配属于其父元素的唯一子元素的每个元素。
:nth-child(n) 选择器匹配属于其父元素的第n个子元素,不论元素的类型。
:enabled :disabled 表单控件的禁用状态。
:checked 选择器匹配每个选中的输入元素(仅适用于单选按钮或复选框)。

 

1.6. css的函数有哪些

rgb() 使用红(R)、绿(G)、蓝(B)三个颜色的叠加来生成各式各样的颜色。
rgba() 使用红(R)、绿(G)、蓝(B)、透明度(A)的叠加来生成各式各样的颜色。
var() 用于插入自定义的属性值。
calc() 允许计算 CSS 的属性值,比如动态计算长度值。
attr() 返回选择元素的属性值。
cubic-bezier() 定义了一个贝塞尔曲线(Cubic Bezier)。
hsl() 使用色相、饱和度、亮度来定义颜色。
linear-gradient() 创建一个线性渐变的图像
...
差不多就行了

1.7. 为什么要初始化css,css标签命名规范有哪些

初始化css

初始化css是因为浏览器的差异,并且初始化可以提高编码质量

最常用的初始化 *{padding:0;margin:0;}不建议使用

举个例子:在公共样式里面把a,a:hover,ul,ol,button等的默认样式去掉,这就叫做css的初始化

css命名规范

头:header  内容:content/container  尾:footer  导航:nav  侧栏:sidebar

栏目:column  页面外围控制整体布局宽度:wrapper  左右中:left right center

登录条:loginbar  标志:logo  广告:banner  页面主体:main

 

1.8. 如何给全局css增加样式

2.html

2.1. html5有哪些新特性,移除了哪些元素

新特性

绘画元素:canvas

媒体元素:

       video,audio

本地离线存储:

        localStorage长期存储,sessionStorage关闭自动清除

语义化标签:

        footer,header,nav,section

表单控件:

        date,time,email,search

移除

        纯表现元素:big,center,font,s等

        产生负面影响的元素:frame等

 

2.2. canvas与svg的区别

两个都允许在浏览器中创建图形,但是canvas是点状图,放大会失真(模糊);svg是矢量图,是使用xml描述的2D图形语言,放大不会失真

2.3. 如何使用svg和canvas分别画一条线

//svg画矩形
<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg">
    <path d="M0 0 L150 0 L150 75 L0 75 L0 0 Z" style="fill:white;stroke:red;"/>
</svg>

//canvas画矩形
var c=document.getElementById("myCanvas");//获取canvas元素
var cxt=c.getContext("2d");//创建 context 对象,getContext("2d") 对象是内建的 HTML5 对象,拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。
cxt.fillStyle="#FF0000";//边框颜色
cxt.fillRect(0,0,150,75);//绘制

2.4. 谈谈html,css,javascript的区别

比较形象的说就是html相当于人类的骨架,css是人类的形象,javascript是人类的动作

3.javascript

3.1. js的类型有几种类型

//基本数据类型
String,Number,Boolean
//引用类型
Object,Array,function
//特殊类型
undefined,null

3.2. js中this的指向,改变this指向的方法

this 是和执行上下文绑定的,也就是说每个执行上下文中都有一个 this。
this指向分很多种情况,一般this是谁调用就指向谁,this默认指向的时window对象,但是在严格模式下this的指向是undefined
例1
function a(){
    var b = 'name';
    console.log(this.b);//undefined
    console.log(this);//window
}
a();
其实这样子调用a函数的时候等于是window在调用,window.a()

例2
var o = {
    a:10,
    c:'name',
    b:{
        a:12,
        fn:function(){
            console.log(this.a); //12
            console.log(this.c); //undefined
        }
    }
}
o.b.fn();
这里面this其实指向的是b

例3
var o = {
    a:10,
    b:{
        a:12,
        fn:function(){
            console.log(this.a); //undefined
            console.log(this); //window
        }
    }
}
var j = o.b.fn;
j();
这里你要记住this的指向是最后调用它的对象,在这里o.b.fn只是赋值给了j,并没有调用,最终调用的还是window.j();

例4
构造函数版
function a(){
    this.name = "name";
}
var b = new a();
console.log(b.name); //name
这里面因为使用了关键字new创建了一个对象实例,并把a函数复制了一份给b,所以b中就有了name属性

当构造函数碰到return时,如果return的时对象那么this的指向就是return的这个对象,如果return的不是对象,那么this的指向还是函数的实例
例5
function a(){
    this.name = "name";
    return 1 //或者return null(虽然null也是对象,但是在这里比较特殊)
}
var b = new a();
console.log(b.name);//name

例6
function a(){
    this.name = "name";
    return {} //或者return function(){}
}
var b = new a();
console.log(b.name);//undefined

箭头函数this的指向
箭头函数不绑定this,会捕获其所在的上下文的this值,作为自己的this值。
任何方法都改变不了其指向
例7
var obj = {
  a: 10,
  b: () => {
    console.log(this.a); // undefined
    console.log(this); // Window
  },
  c: function() {
    console.log(this.a); // 10
    console.log(this); // {a: 10, b: ƒ, c: ƒ}
  }
}
obj.b(); 
obj.c();

改变this指向的方法
call、apply
当函数通过Function对象的原型中继承的方法 call() 和 apply() 方法调用时, 其函数内部的this值可绑定到 call() 与 apply() 方法指定的第一个对象上, 如果第一个参数不是对象,JavaScript内部会尝试将其转换成对象然后指向它。
例8
function add(c, d){
  return this.a + this.b + c + d;
}
var o = {a:1, b:3};
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34
function tt() {
  console.log(this);
}
// 返回对象见下图(图1)
tt.call(5);  // Number {[[PrimitiveValue]]: 5} 
tt.call('asd'); // String {0: "a", 1: "s", 2: "d", length: 3, [[PrimitiveValue]]: "asd"}

bind
bind方法在ES5引入, 在Function的原型链上, Function.prototype.bind。通过bind方法绑定后, 函数将被永远绑定在其第一个参数对象上, 而无论其在什么情况下被调用。
例9
function f(){
  return this.a;
}
var g = f.bind({a:"azerty"});
console.log(g()); // azerty
var o = {a:37, f:f, g:g};
console.log(o.f(), o.g()); // 37, azerty

3.3. 什么是闭包,他的优缺点有哪些

通俗点闭包就是函数内部写函数,或者能够读取其他函数内部变量的函数

优点:

1. 避免使用全局变量,防止全局变量污染;

2. 局部变量会常驻在内存中;

3. 可以让外部变量访问函数内部的变量;

4. 减少传递函数的参数量

缺点:

1. 占有内存资源,造成内存泄漏,

解决:

把不需要的变量又无法回收的赋值为null

 

3.4. 什么是原型,原型链又是什么

每个对象都会在内部初始化一个属性,这个属性就是原型(propertype)

当访问对象的属性时,如果这个对象没有这个属性,那么会去这个对象的原型上面去找,如果这个原型也没有这个属性,因为原型也有自己的原型,那么就会去这个原型的原型上去找,一层一层的找下去就是原型链

3.5. 什么是作用域,作用域链是什么

作用域分为全局作用域和局部作用域;

当函数内部访问某个变量时,如果当前函数内部找不到(也就是当前作用域),会去上一级作用域去找,一直找到全局作用域,这么一层一层找下去就是作用于域链

3.6. 谈谈链式函数

链式函数让代码更加简洁,易读,同时可以避免多次重复使用一个对象变量

3.7. 解释DOM事件模型

事件是用户或者浏览器自己执行的某种动作,是文档或者浏览器发生的一些交互瞬间,比如点击(click)按钮等,这里的click就是事件的名称。JS与html之间的交互是通过事件实现的,DOM支持大量的事件。

事件流

DOM是个树形结构,当我们点击一个按钮,页面上哪些元素会触发这个事件;

事件冒泡

事件冒泡时IE的事件流,事件是由最具体的元素接收,从内往外传播,一直到document,谷歌到window

简单点就是从内到外找监听函数叫事件冒泡

阻止事件冒泡:event.stopPropagation()

事件捕获

事件捕获是从document开始往下传播

简单点就是由外到内找监听函数叫事件捕获(事件监听)

DOM事件流

分为事件捕获阶段,处于目标阶段,事件冒泡阶段;

捕获阶段:事件从window对象自上而下向目标节点传播的阶段;

目标阶段:真正的目标节点正在处理事件的阶段;

冒泡阶段:事件从目标节点自下而上向window对象传播的阶段

IE 事件处理程序

事件绑定监听函数:attachEvent(eventType, listener)
事件移除监听函数:detachEvent(eventType, listener)

w3c 事件处理程序

事件绑定监听函数:addEventListener(eventType, listener)
事件移除监听函数:removeEventListener(eventType, listener)

3.8. 说下promise的静态方法

Promise.all(Array) 同时监听多个Promise的实例

Promise.race(Array) 同时监听多个Promise,根据最快发生状态变化的实例

Promise.resolve() 用于将非Promise转为Promise实例

3.9. 了解过函数的防抖和节流吗,他们的区别是什么?分别应用场景又哪些

防抖

一个频繁触发的函数,在规定时间内,只让最后一次生效。

原理

在第一次调用函数的时候,创建一个定时器,在指定的时间间隔之后运行代码; 如果代码还没运行时,又触发了该函数,则清除旧的定时器,重新创建新的定时器; 如果超过延时执行的时间,代码执行了,则此时已经时第二次触发了。

function debounce(func, delay) {
   let timeout
   return function() {
      clearTimeout(timeout) // 如果持续触发,那么就清除定时器,定时器的回调就不会执行。
      timeout = setTimeout(() => {
          func.apply(this, arguments)
      }, delay)
   }
}

 

 

应用场景

频繁操作点赞和取消点赞的时候,search搜索联想,用户在不断输入值时,点击提交

节流

一个频繁触发的函数,在规定时间内,函数只执行一次

原理

第一次执行函数的时候,记录函数执行的时间,当下一次执行的时候,比较时间是否还在间隔时间内,如果是则不执行,否则继续执行;

function throttle(func, delay) {
    let run = true
    return function () {
      if (!run) {
        return  // 如果开关关闭了,那就直接不执行下边的代码
      }
      run = false // 持续触发的话,run一直是false,就会停在上边的判断那里
      setTimeout(() => {
        func.apply(this, arguments)
        run = true // 定时器到时间之后,会把开关打开,我们的函数就会被执行
      }, delay)
    }
}

 

应用场景

一般在onresize/mousemove/onscroll等事件中,防止过多的请求造成服务器压力

 

3.10. ES6中如何实现继承的

es6通过class定义一个类,使用extends实现继承,super指向父类的原型对象

class Parent {
    constructor(name,age){
        this.name = name
        this.age = age
    }
    sayName(){
        console.log(this.name);
    }
}

class Child extends Parent{
    constructor(name,age,gender){
        super(name,age)
        this.gender = gender
    }
    sayGender(){
        console.log(this.gender);
    }
}


//实例化
const obj = new Child('w',18,'男')
obj.sayGender()
obj.sayName()
console.log(obj.name);
console.log(obj.age);

 

3.11. 谈谈var,let,const的区别,const声明的常量可以改变吗?

同一作用域let声明变量重复时,会报错,而var不会,var会直接覆盖,

var存在变量的提升,let不存在变量提升

const声明的时常量

当const声明的值是基本数据类型时,值不可变,会报错

当const声明的值是引用数据类型时,值可变,地址不变,

原因

'基本数据类型‘的 值就保存在内存地址中,所以const定义的 ‘基础数据类型’ 不可被改变。 

而 '引用数据类型’ 指向的内存地址只是一个指针,通过指针来指向实际数据,也就是说,不可被改变的是指针,而不是数据,所以const定义的 ”引用数据类型的‘ 常量可以通过属性来修改值。这就牵扯出栈内存和堆内存。

3.12. 谈谈浏览器的离线存储技术,他们有哪些区别

Cookie 4K,浏览器关闭,丢失,通过http头信息可以延长;

LocalStorage 5M,没有时间限制,缺点:localStorage在浏览器的隐私模式下面是不可读取的;localStorage不能被爬虫抓取到,localStorage本质上是对字符串的读取,如果存储内容多的话会消耗内存空间,会导致页面变卡;

SessionStorage 5M,浏览器关闭,清空

3.13. 变量在内存中如何体现

基本数据类型是保存在栈内存中的简单数据段,它们的值都有固定的大小,保存在栈空间,通过按值访问

引用数据类型是保存在堆内存中的对象,值大小不固定,栈内存中存放的该对象的访问地址指向堆内存中的对象,JavaScript不允许直接访问堆内存中的位置,因此操作对象时,实际操作对象的引用

3.14. 谈谈对深拷贝和浅拷贝的区别

深拷贝就是为新对象开辟了一个新内存,所以对新对象上进行操作不会影响旧的对象,浅拷贝就是新对象只是复制了一份旧对象的指针,而这个指针指向的还是看对象,所以修改新对象会影响老对象的值

深拷贝实现原理

function deepClone(params) {
    if (typeof params !== 'object' || params == null) { // 先排除参数是基本类型的情况
        return params
    }
    let result;
    if (params instanceof Array) { // 这里判断是数组还是对象
        result = []
    } else {
        result = {}
    }
 
    for (const key in params) { // 遍历数组或对象进行多轮遍历
        if (params.hasOwnProperty(key)) { // hasOwnProperty 可以排除非自身(非继承)属性。 判断自身属性是否存在
            result[key] = deepClone(params[key])
        }
    }
 
 
    return result
}

深拷贝方法JSON.parse(JSON.stringify())

浅拷贝方法Array,prototype.slice(),Array.prototype.concat(),Object.assign()

3.15. 什么是事件委派(代理),具体实现原理

事件委托简单的说就是将事件交由别人来执行,就是将子元素的事件通过冒泡的形式交由父元素来执行。

好处

  • 只绑定一次事件,无频繁访问DOM,性能较高,
  • 当有新DOM生成时,无需重复绑定事件,代码清晰简洁

实现原理

var oUl = document.getElementById("ul");
oUl.onclick = function(ev){
    var ev = ev || window.event;
  var target = ev.target || ev.srcElement;// target表示在事件冒泡中触发事件的源元素,在IE中是srcElement  
  if(target.nodeName.toLowerCase() == 'li'){
     alert(123);
     alert(target.innerHTML);
  }
}

3.16. 说一下事件循环模型,以及宏任务和微任务

因为 js 是单线程的,需要处理异步任务就需要建立一些任务队列,然后不断循环去取任务(宏任务和微任务)出来执行。

宏任务(Macrotask): 鼠标事件,键盘事件,ajax, setTimeout ,setInterval, 主线程的整体代码(script标签)也是一个宏任务

微任务(Microtask): process.nextTick, Promise.then(), MutaionOberver

执行顺序

  1. 执行宏任务队列中的第一个任务,执行完后移除它
  2. 执行所有的微任务,执行完后移除它们
  3. 执行下一轮宏任务(重复步骤2)

3.17. 跨域问题的前端解决办法,为什么会出现跨域

JSONP

浏览器同源策略

3.18. promise手动实现的大体流程

3.19. server代理是如何实现的,为什么可以解决跨域,以及为什么只能在开发环境中使用

3.20. 谈谈对js设计模式的理解,以及项目中用到了哪些设计模式

3.21. 项目架构是什么样子的

3.22. 递归和迭代的区别,各有什么优缺点,尾调用是什么

3.23. 函数式编程与面向对象编程冲突吗?为什么

3.24. 谈谈对依赖注入的理解

为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。

3.25. 什么是策略模式和单例模式

3.26. 什么是MVVM,MVC,MVP他们之间有什么区别,和优缺点

4.VUE

4.1. vue生命周期的理解

4.2. vue双向绑定的原理

4.3. vue又哪些指令,分别是做什么的

4.4. v-show和v-if的区别

4.5. vue父子组件之间的通讯,又多少种方式

4.6. vue路由钩子有哪些

4.7. vuex是什么,哪种场景何以用到

4.8. 了解过vue当中的依赖注入吗

4.9. vue动态路由如何实现的

4.10. 什么是模板编译(编译模板),什么是预编译,编译模板的原理是什么

4.11. 如何对vue进行优化

4.12. 平时项目你封装过哪些组件

4.13. vue和react的区别和优缺点

5.小程序、移动端

5.1. 移动端如何做适配

5.2. 小程序的生命周期

5.3. 小程序的APPID如何获取

5.4. 小程序如何分包

评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值