前端面试题整理

VUE


  1. Vue 组件中 data 为什么必须是函数
    因为一个组件是可以共享的,但他们的data是私有的,所以每个组件都要return一个新的data对象,返回一个唯一的对象,不要和其他组件共用一个对象。

  2. 说一下v-if和v-show的区别
    v-if和v-show都可以显示和隐藏一个元素,但有本质区别。
    v-if是惰性的,只是值为false就不会加载对应元素,为true才动态加载对应元素。
    v-show:是无论为true和为false都会加载对应html代码,但为false时用display:none隐藏不在页面显示,但为true时页面上用display:block显示其效果。

    适用场景:切换频繁的场合用v-show,切换不频繁的场合用v-if

  3. 说一下vue自定义指令如何实现的和适用场景?
    全局自定义指令:Vue.directive(‘指令名’,{ inserted(el) { } })
    局部自定义指令:directives:{ }

  4. 什么是mvvm?
    MVVM是model-view-viewModel的缩写.是一种设计思想。Model层代表数据模型,用于定义数据修改和操作的业务逻辑;View代表UI组件,负责将数据模型转化为UI展现出来,ViewModel是一个同步View和Model的对象。
    在MVVM架构下,View和我Model之间并没有知己饿的联系,而是通过ViewModel进行交互。

  5. vue的优点是什么?
    a. 低耦合:视图View可以独立于Model变化和修改,一个ViewModel可以绑定到不同给的“view”上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
    b. 可重用性:你可以把一些视图逻辑放在ViewModel里面,让很多view重用这段视图逻辑。
    c.独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。
    d.可测试:界面素来是比较难测试的,而现在测试可以针对ViewModel来写。

  6. vue之间是怎么传值的
    -父组件与子组件传值
    父组件通过标签上定义传值(:父组件名称=”子组件props的名称”)
    子组件通过props的方式接受数据
    -子组件向父组件传递数据
    子组件通过$emit方法传递参数给父组件

  7. v-show和v-if之间的区别
    v-show指令是通过修改元素的display的CSS属性让其显示或隐藏。
    v-if指令是直接销毁和重建DOM节点,达到让元素显示和隐藏的效果。

  8. 的作用是什么?
    keep-alive标签包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染。

  9. 指令v-el的作用是什么?
    提供一个在页面上已存在的DOM元素作为Vue实例的挂载目标,可以是CSS选择器,也可以是一个HTMLElement实例。

  10. 为什么使用key?
    当有相同标签名的元素切换时,需要通过key特性设置唯一的值来标记已让vue区分它们,否则vue为了效率只会替换相同标签内部的内容。

  11. 为什么要避免v-if和v-for一起使用?
    当vue处理指令时,v-for比v-if具有更高的优先级,通过v-if移动到容器元素,不会再重复遍历列表中的每个值,取而代之的事,我们只检查它一次,且不会再v-if为否的时候运行v-for。

  12. Vue的双向数据绑定原理是什么?
    vue.js是才用数据劫持介个发布-订阅者模式的方法,通过object.defineProperty()来劫持各个属性的setter和getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

  13. 生命周期
    生命总共分为8个阶段创建前/后、载入前/后、更新前/后、销毁前/后
    创建前/后 : 在beforeCreate阶段,vue实例的挂载元素el和数据对象data都为undefined,还未初始化。在created阶段,vue实例的数据data有了,el还没有。
    载入前/后:在beforeMount阶段,vue实例的$el和data都初始化了,单还没有挂载之前都是虚拟的demo阶段,data.message还未替换.在mounted阶段,vue实例挂载完后,data.message成功渲染.
    更新前/后:当data变化时,户触发beforeUpdata和updata方法。
    销毁前/后:在执行destroy方法后,对data的改变不会再触发周期函数,说明此时vue实例已经结束了事件监听以及和dom的绑定,但是dom结构依然存在。

  14. 怎么定义vue-router的动态路由以及如何获取传过来的动态参数?
    在router目录下的index.js文件中,对path属性加上/:id。
    使用router对象的params id。

  15. vuex的五大属性
    Vue有五个核心概念:state、getters、mutations、actions、modules。
    state => 基本数据。
    getters => 从基本数据派生的数据。
    mutations => 提交更改数据的方法,同步!
    actions => 像一个装饰器,包裹mutations,使之可以异步。
    modules => 模块化Vuex。

  16. 不使用vuex有什么影响
    1)可维性会下降,想修改数据要维护三个地方。
    2)可读性会下降,因为一个组件里的数据,根本就看不出来是从哪来的。
    3)增加耦合,大量的上传派发,会让耦合性大大增加。而Vue用Component就是为了减少耦合。

React部分:


1. react事件机制:

  • react不是给真实dom添加的事件,而是在document处监听了所有事件,运用冒泡原理,在document处,react将事件内容封装并交由真正的处理函数运行,这样不仅减少了内存的消耗,还能再组件销毁时统一订阅和移除事件。
    冒泡到document上的事件也不是原生的浏览器事件,而是由react自己实现的合成事件,react中阻止事件冒泡,只能使用event.stopProppagation()方法,而不能使用event.preventDefault()方法

  • 实现合成事件的目的:
    - 合成事件首先抹平了浏览器之间的兼容问题,其次这是一个跨浏览器原生事件包装器,赋予了跨浏览器开发的能力
    - 低于原生浏览器事件来说,浏览器会给监听器创建一个事件对象。如果有很多的事件监听,那就需要分配很多的事件对象,浪费内存。对于合成事件来说,有一个事件池专门来管理他们的销毁和创建,当事件需要被使用时,就会从池子中复用对象,事件回调结束后,就会销毁事件对象上的属性,从而便于下次复用事件对象

  1. react事件和普通事件有什么不同
    事件命名方式不同,原生事件为全小写,react事件采用小驼峰;
    对于事件函数处理语法,原生事件为字符串,react为函数;
    react事件不能采用return false的方式来阻止浏览器默认行为,而必须要明确的调用preventDefault()来阻止默认行为

  2. react.component 和 react.purecomponent的区别
    purecomponent表示一个纯组件,可以用来优化react程序,减少render函数执行的次数,从而提高组件的性能。purecomponent会自动执行shouldcomponetupdate函数。但是purecomponent中的shuldcomponentupdate进行的是浅比较,如果是医用数据类型的数据,只会比较引用地址。

  3. react在render中能访问refs吗?为什么?
    不能,因为render阶段dom还没有生成,无法获取dom,dom的获取需要在pre-commit阶段和commit阶段

  4. 类组件和函数组件的区别
    相同点: 都可以接受属性并返回react元素
    不同点:
    (1)类组件需要创建实例,是基于面向对象的方式编程,函数组件不需要创建实例,基于函数编程的思想
    (2)类组件需要创建并保持实例,会占用一定的内存,函数组件不需要创建实例,可以节约内存占用。
    (3)类组件有完整的生命周期,函数组件没有生命周期。
    (4)类组件通过shouldcomponent和purecomponent跳过更新,而函数组件可以通过react.memo跳过更新
    (5)类组件复用逻辑一般用hoc,函数组件可以自定义hook。

  5. setState是同步还是异步
    (1)react生命周期中以及事件处理中,为异步。
    (2)原生方法中是同步。

  6. 调用setState的时候,发生了什么?
    react会将传入的参数对象与组件当前的状态合并,然后出发所谓的调和过程,经过调和过程,reaact会以相对高效的方式根据鑫的状态构建react元素树并着手重新渲染整个UI界面,在react得到元素树后,react会自动计算出新的树与老的树的节点差异,然后根据差异对界面进行最小化冲渲染。

  7. 什么时react的refs?为什么很重要?
    refs允许直接访问DOM元素或者组件实例,也可以通过ref访问子组件的方法。
    本质为ReactDOM.render()返回的组件实例,如果时渲染组件则返回的时组件实例,如果渲染dom则返回的时具体的dom节点。
    如果该值是一个字符串,react将会在组件实例化对象的refs属性中,存储一个同名属性,改属性是对这个DOM元素的引用。可以通过原生的DOM API操作。
    如何使用:
    · 传入字符串,使用时通过this.refs.传入的字符串的格式获取对应的元素。
    · 传入对象,对象是通过React.createRef()方式创建出来的,使用时获取到创建的对象中存在current属性就是对应的元素。
    · 传入函数,该函数会在DOM被挂载时进行回调,这个函数会传入一个元素对象,可以自己保存,使用时,直接拿到之前保存的元素对象即可。
    · 传入hook,hook时同故宫useRef()方式创建,使用时通过生成hook对象的current属性就是对应的元素。

应用场景

·	对DOM元素的焦点控制、内容选择、
·	对DOM元素的内容设置及媒体播放
·	对DOM元素的操作和对组件实例的操作
·	获取子组件中的方法等
  1. setState第二个参数有什么用?使用它的目的是什么?
    一个回调函数,当setState方法执行结束并重新渲染该组件的时候调用。
    用于监听渲染是否完成。

  2. vue和react的不同点
    (1)react严格上针对的是mvc模式的view层,vue则是mvvm模式。
    (2)操作dom的方式不同,vue使用的是指令操作dom,react是通过js进行操作。
    (3)数据绑定不同,vue实现的是双向绑定,react的数据流动是单项的。
    (4)react中的state是不能直接改变的,需要使用setState改变。vue中的state不是必须的,数据主要是由data属性在vue对象中管理的。

  3. react性能优化的方案
    (1)重写shouldComponentUpdate来避免不必要的操作。
    (2)使用production版本的react.js。
    (3)使用key来帮助react识别列表中所有子组件的最小变化。

  4. 简述state和props的理解,有啥区别
    state:
    · 组件数据来源之一,一般在constructor中初始化。
    · 需要修改state时,需要调用setState。

    props:
    ·	组件接收的从外部传入的参数。子组件中的props不可更改。
    ·	从父组件流向子组件。
    
    相同点:
    ·	两者都是js对象。
    ·	两者都可以用于保存数据。
    ·	都能出发render。
    
  5. 为什么虚拟DOM会提高性能
    虚拟DOM是JS对象,时一个真实DOM的JS对象;虚拟DOM相当于在JS和真是DOM中加了一个缓存,利用DOM DIFF算法避免了没有必要的DOM操作,从而提高了性能,

  6. 为什么react router中使用switch关键字
    由于router和switch对于路由的渲染策略不同,对router来说,如果有的链接既可以被路由A匹配,又可以被路由B匹配,那么router会同时渲染
    对于switch来说,它只会渲染符合条件的第一个路径,避免重复匹配。

  7. 生命周期:
    一.初始化阶段
    getDefaultProps:获取实例的初始化状态
    getInitialState: 获取每个实例的初始化状态
    componentWillMount:组件即将被装载、渲染到页面上
    render:组件在这里生成虚拟的DOM节点
    componentDidMount:组件真正在被装载之后
    二.运行中状态
    componentWillReceiverProps:组件将要接收到属性的时候调用
    shouldComponentUpdate:组件接受到新属性或者新状态的时候(可以返回false,接受数据后不更新,组织render调用,后面的函数不会被继续执行了)
    componentWillUpdate:组件即将更新不能修改属性和状态
    render:组件重新描绘
    三.销毁阶段
    componentWillUnmount:组件即将销毁

JS部分

  1. ES6中箭头函数与普通函数的区别
    (1)普通函数的声明在变量提升中是最高的,箭头函数没有函数提升。
    (2)箭头函数没有this,arguments。
    (3)箭头函数不能作为构造函数,不能被new,没有property。
    (4)call和apply方法只有参数,没有作用域。

  2. 什么是闭包,有什么危害?
    闭包就是一个定义在函数内部的函数。因为js中存在作用域的问题,所以在函数内部定义的变量在函数外部是没有办法直接获取到的。闭包可以实现函数属性和方法的私有化。
    因为闭包会将内部变量存储在内存中,如果长时间不清除的话,会造成内存泄漏问题,影响程序的性能。

  3. 创建对象的方法
    (1)字面量方式

	const obj = {
		name: 'obj',
		eat:function(){
			console.log('this is a obj')
		}
	}
(2)通过构造函数创建
const obj = new 函数名();

eg: 
	function Person(name, sex){
		this.name=name;
		this.age = sex;
		this.job = function(){
			console.log(this.name);
		}
	}
	const child = new Person('guaiguai', '女');
	Person.job();
(3)通过new关键字创建
	const person = new Object();
	person.name = 'xiaokuoai';
	person.jon = function(){
		console.log('xiaokuoai');
	}
(4)工厂方式
		function(name, age){
			const stu = new Object();
			stu.name = name;
			stu.age = age;
			stu.job = function(){
				console.log(this.name+'学习...');
			}
			return stu;
		}
  1. 判断对象是否拥有某一属性
    (1)可以用in操作符
	const obj = {
		name: 'ming',
		age: 12
	};
	'name' in obj; // true
	'sex' in obj; // false
	// 注意:如果obj的原型链上能找到其他属性,则in操作符返回为true(继承)
	'toString' in obj; // true   继承得到的属性同样返回true
(2)hasOwnProperty()  可以判断一个属性是否是该对象自身拥有的
	const owner = {
		name: 'ow'
	}
	owner.hasOwnProperty('name'); // true
	owner.hasOwnProperty('age');  //  false
  1. Math
    (1) Math.trunc() – 用于去除一个数的小数部分,返回整数部分。对于非数值它会内部调用Number方法先将其转换为数值。
    (2) Math.sign() – 判断一个数是正数、负数、零或者NaN。对于非数值,会将其转换成数值。返回五种值:
    a:参数为正数,返回 +1;
    b:参数为负数,返回 -1;
    c:参数为0,返回 0 ;
    d:参数为-0, 返回-0;
    e:其他值,返回NaN;
    (3) Math.sqrt(x) – 求x的开平方
	Math.sqrt(25); // 5
  • (4)Math.pow(x,y) – 求x的y次方
  1. Number
    (1)isFinite();----检测是否是有限的数字,即不是Infinity。如果参数不是数字直接返回false。
    (2)isNaN();----判断参数是不是NaN;
    (3)parseInt();----将字符串转为整树;
    (4)parseFloat();----将字符串转为浮点数;
    (5)isInteger();----判断一个数值是否为整数【如果数字超过了小数点后面的十六个进制则会判断失误。因为超过的被遗弃了。或者绝对值小于js能判断的最小值也会失误被转为0】

  2. string方法
    (1)charAt(index) ---- 获取index位置处的字符
    (2)charCodeAt(index)---- 获取index位置处字符的unicode编码
    (3)string.fromCharCode(code) ---- 将unicode编码转换为对应的字符串
    (4)concat() ---- 链接字符串
    (5)lastIndexOf(sub) ---- 查找符合条件的第一个字符串所在下标(从后往前查)
    (6)slice(start,end) ---- 截取子字符串
    (7)subString(start,end)---- 截取子字符串,不包括endIndex
    (8)split() ---- 切割字符串,将字符串以指定字符切割成数组
    (9)replace(oldString,newString) ---- 替换
    (10)trim() ---- 去掉前后空白
    (11)includes(sub)---- 返回布尔值,表示是否找到参数字符串
    (12)padStart() ---- 补全头部
    (13)padEnd()----补全尾部4
    (14)matchAll() ---- 返回一个正则表达式在当前字符串的所有匹配

  3. JSON
    (1)JSON.stringify() ---- 将js值转为JSON文本字符串
    (2)JSON.parse() ---- 将json文本字符串转为js值
    (3)encodeURIComponent() ---- 编码
    (4)decodeURIComponent() ---- 解码

  4. Array
    (1)push() ---- 向原数组末尾添加元素,返回新长度,会改变原数组
    (2)unshift()---- 向原数组开头添加元素,返回新长度,会改变元数组
    (3)splice(index,howmany,value1,value2…)---- 新增/删除指定索引元素,改变原数组
    (4)pop()---- 删除数组最后一位元素,返回被删除的元素,改变原数组
    (5)shift()---- 删除头部元素,返回被删除的元素,改变原数组
    (6)sort() ---- 排序,改变原数组,返回新数组
    (7)concat() ---- 连接多个数组,返回新数组,不改变原数组
    (8)join()---- 将数组的每个元素以指定分隔符连接成字符串,返回字符串
    (9)slice(start,end) ---- 从start返回截取指定索引范围内的元素,如果不传值,则相当于直接拷贝了一份数组的值,end可以不传,表示截取到最后一位,start与end可以传负值,表示从后往前计数,返回新数组,不改变原数组
    (10)toString()---- 转换为字符串,和不传参数的join一样,还可以使用2,8,16进制转变为不同结果
    (11)flat()---- 数组降维,Infinity降至一维,不改变原数组,返回新数组

  5. 什么是原型链
    所有的函数都有prototype属性
    所有的对象都有__proto__属性
    在js中,每个函数都有一个原型属性protorype指向自身的原型,而由这个函数创建的对象也有一个proto属性指向这个原型,而函数的原型是一个对象,所以这个对象也会有一个proto指向自己的原型,这样逐层深入指导Object对象的原型,这样就形成了原型链。

  6. JS的垃圾回收机制
    (1)概述:
    JS的垃圾回收机制是为了防止内存泄漏,垃圾回收机制就是不停歇的寻找这些不再使用的变量,并且释放掉它所指向的内存。
    (2)变量的声明周期
    当一个变量的生命周期结束后,它所指向的内存就会被释放。JS由两种变量,局部变量和全局变量,局部变量是在他当前的函数中产生作用,该函数结束之后,该变量内存会被释放,全局变量的话会一直存在,直到浏览器关闭为止。
    (3)JS垃圾回收方式
    由两种方式:标记清楚、引用计数
    标记清除:当变量进入执行环境(声明变量)的时候,垃圾回收器将该变量进行了标记,当该变量离开环境的时候,将其在度标记,随之进行删除
    引用计数:跟踪某一个值的引用次数,当声明一个变量并且将一个引用类型赋值给变量的时候引用次数加1,当这个变量指向其他一个时引用次数减1,当为0时触发回收机制进行回收。

  7. Async和Await如何通过同步的方式实现异步
    async/await时Generator的语法糖,就是一个自执行的Generate函数,利用generate函数的特性把异步的代码写成“同步”的形式。

  8. setTimeout、Promise、Async/Await 的区别
    setTimeout属于宏任务,Promise里面的then方法属于微任务,Async/await中await语法后面紧跟的表达式是同步的,但接下来的代码是异步的,属于微任务。
    Promise本身是同步的,但在执行resolve或者rejects是异步的,即then方法是异步的。

  9. 说说JS作用域

    JS作用域也就是JS识别变量的范围,作用域链也就是JS查找变量的顺序。
    JS作用域主要包括全局作用域、局部作用域和ES6的块级作用域。
    全局作用域:也就是定义在window下的变量范围,在任何地方都可以访问。
    局部作用域:是只在函数内部定义的变量范围
    块级作用域:简单来说用let和const在任意的代码块中定义的变量都认									为是块级作用域中的变量,例如在for循环中用let定义的变量,在if语句中用let定义的变量等等。
    **注:尽量不要使用全局变量,因为容易导致全局的污染,命名冲突,对bug查找不利。**
    
  10. 深拷贝,浅拷贝
    浅拷贝: 直接赋值,Object.assign({},{})
    深拷贝:递归,Object.assign({},{})

  11. this指向问题:
    - this总是直接指向函数的调用者
    - 如果有new关键字,this指向new出来的对象
    - 在事件中,this指向事件的调用者
    - 在计时器中,this的指向是windows
    - 箭头函数中,this总是指向上一个作用域

  12. 箭头函数和普通函数的区别
    - 函数体内的this对象,就是定义时所在的对象,而不是调用时所在的对象
    - 可以当作构造函数(不能使用new字符);
    - 该函数内没有arguments对象,如果需要使用,可以使用rest代替
    - 不能使用yeild命令,因此肩头函数不能被用作Generator函数

其他

  1. sass和less的区别
    定义变量的符号不同,less是用@,sass是用$
    变量的作用域不同,less在全局定义,就作用在全局,在代码块中定义,就作用于整个代码块。而sass只作用于全局。
    编译环境不同,less在开发者环境编译,sass在服务器环境下编译。

  2. 如何解决跨域
    (1)jsonp
    (2)document.domain + iframe
    (3)nodejs中间件代理跨域
    (4)后端在头部信息里面设置安全域名

  3. 项目性能优化
    (1)减少HTTP请求次数
    (2)减少DNS查询
    (3)使用CDN
    (4)避免重定向
    (5)图片懒加载
    (6)减少DOM元素元素数量
    (7)减少DOM操作
    (8)使用外部JS和CSS
    (9)压缩JS、CSS、字体、图片等
    (10)优化CSS Sprite
    (11)使用iconfont
    (12)尽量减少iframe的使用
    (13)避免图片src为空
    (14)把JS放在页面底部
    思维导图:

在这里插入图片描述

  1. 浏览器中输入url到网页显示,整个过程发生了什么
    DNS域名解析
    建立tpc ip协议,发送http请求
    服务器端响应http请求,浏览器得到html代码
    浏览器解析html代码,并请求html代码中的资源
    浏览器对页面进行渲染呈现给用户

  2. 安全性问题
    (1)XSS攻击:注入恶意代码
    - cookie设置httpOnly
    - 转义页面上的输入内容和输出内容
    (2)CSRF:跨站请求伪造,防护:
    - get不修改数据
    - 不被第三方网站访问到用户的cookie
    - 设置白名单,不被第三方网站请求
    - 请求校验

  3. CDN

    • 什么是CDN?
    •   是一组分布在各个地区的服务器。这些服务器存储着数据的副本,因此服务器可以根据哪些服务器与用户距离近,来满足数据的请求。CDN提供快速服务,较少受高流量影响。
      
    • 为什么要用CDN?
    •   提升响应速度
      
  4. 实现0.5px的实线
    (1){ height: 1px; transform: scaleY(0.5); transform-origin: 50% 100%; }
    (2)boxshadow方法(safari不支持)

{
    height: 1px;
    background: none;
    box-shadow: 0 0.5px 0 #000;
}
(3)svg(firefox不支持)
{
    background: none;
    height: 1px;
    background: url("data:image/svg+xml;utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='100%' height='1px'><line x1='0' y1='0' x2='100%' y2='0' stroke='#000'></line></svg>");
}

svg文件:

<svg xmlns='http://www.w3.org/2000/svg' width='100%' height='1px'>
    <line x1='0' y1='0' x2='100%' y2='0' stroke='#000'></line>
</svg>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值