被面试官问的那些高频面试题---web前端

web前端面试题

一、vue

  1. vue2生命周期钩子函数

beforeCreate:methods声明,生命周期钩子函数声明
created:data数据注入,data数据劫持
beforeMount :此时模板已经编译完成,但还没有被渲染至页面中
mounted :渲染真实DOM
beforeUpdate : 当被劫持的data数据发生变化时,这将经入更新阶段,数据已经发生变化但是视图还未变化
updated :更新真实DOM,视图发生改变
beforeDestroy :销毁前执行,清除计时器、清除非指令绑定的事件等等
destroyed:卸载watcher,事件监听,子组件

  1. 页面首次加载,依次触发的钩子函数

beforeCreate created beforeMount mounted

  1. vue实例中的data属性 在哪些钩子函数中能访问

可以在 created /beforeMount/mounted /beforeUpdate /updated /beforeUnmount 访问

  1. 对一个响应式变量赋值,最好不要在钩子函数updated中,不然会造成死循环

  2. 组件理解:用来实现页面局部功能效果的代码集合

  3. ref和reactive以及toRef、toRefs

都是用来定义响应式变量,使用前import。reactive()用来定义对象,但在对象定义复杂的时候 会出现不能响应的情况。
ref:创建单个响应式变量,修改响应式数据不影响以前的数据;数据改变,界面自动更新
reactive:用于创建一个响应式对象,reactive不能直接赋值,可以Object.assign进行赋值
toRef:引用,修改响应式数据会影响以前的数据;数据改变,界面不自动更新
toRefs:接收一个对象作为参数,它会遍历对象身上所有属性,然后调用单个toRef,将对象的多个属性变成响应式数据,并且要求响应式数据和原始数据关联,且更新响应式数据的时候不会更新界面,用于批量设置多个数据为响应式

  1. 响应式变量驱动视图是 异步线程

  2. nextTick()和onUpdate()的相同和区别

相同:只和视图变化有关
区别:nextTick() 依附逻辑执行 例子体现:VTT-NextTick()

  1. vue2的computed和methods(vue3中的func)的区别 :

computed 在数据没有变化的情况下,会拿缓存数据,节约资源,利用性高;而调用函数会进行重新计算一次

  1. vue Router传值方式

1). query传值 2). params传值 // 语法相同

10.当在一个button 中的click事件的函数逻辑中通过addRoute新增一个路由配置,然后通过编程式路由跳转到该路由配置的path,成功跳转后刷新页面不能正常显示该组件

  1. 在JavaScript中,如何定义一个全局变量?

将变量定义为window对象的属性 window.变量=xx;

  1. 在Vue.js中,如何定义一个全局变量?

将变量定义为当前vue实例的属性 在main.js定义
Vue3:当前vue实例.config.globalProperties.$变量=xx;
Vue2:当前vue实例 .prototype.global = global

  1. 双向绑定的原理

vue实现数据双向绑定主要是采用数据劫持和发布订阅的模式,通过objiect.defineProperty()的get和set,在数据变动的时候发布消息给订阅者,触发消息。

因此接下去我们执行以下3个步骤,实现数据的双向绑定:

  1. 实现一个监听器Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者。

  2. 实现一个订阅者Watcher,每一个Watcher都绑定一个更新函数,watcher可以收到属性的变化通知并执行相应的函数,从而更新视图。

  3. 实现一个解析器Compile,可以扫描和解析每个节点的相关指令(v-model,v-on等指令),如果节点存在v-model,v-on等指令,则解析器Compile初始化这类节点的模板数据,使之可以显示在视图上,然后初始化相应的订阅者(Watcher) 。
    被面试官问的那些高频面试题---web前端_第1张图片

  4. v-model是什么?如何实现双向绑定的

本质是一个语法糖,可以看成input+value的语法糖。可以通过model的prop属性和event事件来进行自定义。用来监听输入的事件以及更新数据。
vue2里面用Object.defineProperty监听每个属性;
vue3里面用new Proxy 监听整个对象。

  1. watch和computed的区别以及watchEffect

watch : 监听属性
不支持缓存,数据变化直接触发响应操作
支持异步
可以监听简单类型也可以监听复杂类型
immediate:组件加载立即触发回调函数执行;
deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用。
当需要在数据变化时执行异步或开销较大的操作时,使用watch

watchEffect:依赖数据更新时重新执行自身
立即执行,没有惰性,页面的首次加载就会执行
无法获取到原值,只能得到变化后的值
不用指明监视哪个属性,监视的回调中用到哪个属性就监视哪个属性

computed:计算属性
页面初始化数据的时候就执行了
不支持异步,当computed内有异步操作时无效,无法监听数据的变化
computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值
计算属性可以是属性值也可以是函数

  1. diff算法是什么以及作用

Diff算法的作用是用来计算出 虚拟 DOM 中被改变的部分,然后针对该部分进行原生DOM操作,而不用重新渲染整个页面

  1. key的作用

在v-for循环中,key的作用通过判断新节点和旧节点的Key是否相等,从而复用与新节点对应的老节点,节约性能的开销。
使用唯一id作为Key值,不建议用index作为key,因为无法被有效复用,新节点需要重新创建

  1. 首屏加载空白的解决方案

首屏需要加载很大的js文件,当网速差的时候会出现一定程度上白屏
解决办法:
优化 webpack 减少模块打包体积,code-split 按需加载
服务端渲染,在服务端事先拼装好首页所需的 html
首页加 loading 或 骨架屏 (仅仅是优化体验)
服务端开启gzip压缩
打包文件分包,提取公共文件包

  1. 祖孙组件传值的方法

祖传孙:

  1. $props 链 :传递次序:GrandFather → Father → GrandSon;
  2. $attrs :直接使用 v-bind=“attrs” 绑定到子组件上;
  3. 祖组件中 写入 provide(‘传递的变量名’,自定义变量名),孙组件中写入inject(‘接收的传递的变量名’)这种方式传递过来的数据是没有响应性的,如果传入了一个可监听的对象,那么其对象的 property 还是可响应的。

孙传组:

  1. $listeners // $emit
  1. mounted()钩子函数与Vue.nextTick()

Vue.nextTick():在Vue生命周期的created()函数中进行DOM操作是要放在Vue.nextTick()回调函数中。原因就是created()在执行的时候DOM只是创建出来并没有渲染在页面上,因此页面上没有这个元素也就无法对其进行操作。
mounted():函数执行时所有的DOM的创建,布局和渲染都已完成。

nextTick()直接放在mounted函数之中是没有作用的,要写在异步函数完成之后。

  1. Pinia和Vuex

由于Pinia是轻量级的,体积很小,它适合于中小型应用。它也适用于低复杂度的Vue.js项目,但一些调试功能,如时间旅行和编辑仍然不被支持。
将 Vuex 用于中小型 Vue.js 项目对性能降低有很大影响,更 适用于大规模、高复杂度的 Vue.js 项目。

  1. pinia的属性:state,getters,action
  2. vuex的属性:
    state(负责状态管理,类似于vue中的data,初始化数据),
    getters(计算属性,相当于vue中的computed),
    mutation(专用于修改state中的数据) ,
    action( 可以处理异步) ,
    module(模块化管理)
  1. vue2和vue3的不同
  1. 响应式原理的不同:vue2 的双向数据绑定是利用Object.definePropert()对数据进行劫持 结合 发布订阅模式的方式来实现的;vue3 中使用了 ProxyAPI 对数据代理。
    vue3使用proxy的优势:
    defineProperty只能监听某个属性,不能对全对象监听
    可以省去for in、闭包等内容来提升效率(直接绑定整个对象即可)
    可以监听数组,不用再去单独的对数组做特异性操作 vue3.x可以检测到数组内部数据的变化
  2. Vue2使用选项类型API(Options API)对比 Vue3合成型API(Composition API),vue3更加简便和整洁
  3. 生命周期钩子
  4. 建立数据 data:
    Vue2 - 这里把数据放入data属性中;在Vue3 - 在setup()方法中(此方法在组件初始化构造的时候触发)。使用reactive//ref 方法来声名我们的数据为响应性数据。
  1. 防抖和节流的使用场景和区别
  1. 防抖(多次触发 只执行最后一次)
    作用: 高频率触发的事件,在指定的单位时间内,只响应最后一次,如果在指定的时间内再次触发,则重新计算时间
    防抖类似于英雄联盟回城6秒,如果回城中被打断,再次回城需要再等6秒
    使用场景:1) .search搜索时,用户在不断输入值时,用防抖来节约请求资源。
  2. 节流 (规定时间内 只触发一次)
    作用: 高频率触发的事件,在指定的单位时间内,只响应第一次
    节流类似于英雄联盟里的英雄平A 一定是内点击多次只进行攻击一次
    使用场景:1).鼠标不断点击触发,mousedown单位时间内只触发一次
    2).监听滚动事件,比如是否滑到底部自动加载更多-------触底加载的优化
  1. promise
  1. Promise 是异步编程的一种解决方案
  2. Promise的实例有三个状态:Pending(进行中)、Resolved(已完成)、Rejected(已拒绝)
  3. then函数中的两个参数:resolved成功回调和rejected失败回调
  4. Promise的catch、then、finally :promise可以链式调用,因为每次调用 .then 或者 .catch 都会返回一个新的 promise
    .finally()方法不管Promise对象最后的状态如何都会执行,他回调函数不接受任何的参数,也就是说你在.finally()函数中是无法知道Promise最终的状态是resolved还是rejected的
  5. Promise的all和race:
    .all()的作用是接收一组异步任务,然后并行执行异步任务,并且在所有异步操作执行完后才执行回调
    .race()的作用是接收一组异步任务,然后并行执行异步任务,只保留取第一个执行完成的异步操作的结果,其他的方法仍在执行,不过执行结果会被抛弃
  1. async和await

也是异步编程的一种解决方案,但它是同步语法来写异步的代码
await只能在async函数中使用,不然会报错
async函数返回的是一个状态为fuifilled(状态为成功)的Promise对象

	const datas = async ()=> {
	  await request.selectPies(Route.path.split('/')[3]).then(res=>{
	  	states.ids = res.obj
	  })
	  await request.selectUsers(states.ids).then(res=>{
	    console.log(res.obj)
	  })
	}
	datas()

二、Js

  1. dom事件的委托原理以及优缺点

事件委托原理:事件冒泡机制,把子元素的事件行为 委托给 父级元素执行
优点:节省内存占用,减少事件注册;新增子对象无需进行事件绑定
缺点:把所有的事件都进行代理,可能会出现事件误判

  1. javascript的事件流模型

事件冒泡:事件逐级向上传播
事件捕捉:事件逐级向下传播,一直到具体
Dom事件流:事件捕捉 目标阶段 事件冒泡

  1. javascript检测一个变量的类型是String的方法
  1. typeof 变量
  2. 变量.constructor===String
  3. Object.prototype.toString.call(变量)//推荐使用

判断变量是数组的方法

  1. Array.isArray(变量)
  2. 变量 instanceof Array
  3. object.prototype.toString.call(变量) === ‘[object Array]’
  4. Array.prototype.isPrototypeOf(变量)
  5. 变量.constructor === Array

几种变量类型判断方法的优缺点

1). typeof
console.log(typeof null) // object
console.log(typeof {}) // object
优点:该方法简单、快速,适用于大多数情况下。
缺点:其中数组、对象、null 都会被判断为 object,无法判断复杂的数据类型如数组和正则表达式,其他判断都正确。

2). instanceof:可以用于判断对象是否为某个构造函数的实例。
console.log(2 intanceof Number) // false
console.log( [] intanceof Array ) // true
优点:可以区分复杂的数据类型如数组和正则表达式。
缺点:无法判断基本数据类型,也无法判断 null 和 undefined 类型。

3). constructor :
function Fn(){}
Fn.prototype = new Array();
var f = new Fn();
console.log( f.constructor === Fn ) // false
console.log( f.constructor === Array ) //true
优点:语法简单,只需访问变量的 constructor 属性即可判断。
缺点:当变量被重新赋值时,可能会出现问题,无法判断 null 和 undefined 类型。

4). Array.isArray()
缺点:只能判断数组类型,无法判断其他数据类型。

5). Object.prototype.toString.call():使用 Object 对象的原型方法toString 来判断数据类型
var a = Object.prototype.toString;
console.log(a.call(2))
优点:可以判断复杂的数据类型,包括数组、正则表达式等。
缺点:需要调用 Object.prototype.toString.call() 方法,语法较复杂

  1. 数组的substr、 substring、 slice以及splice的用法

substr(n,m):截取的是字符串中索引为n开始的,并且截取m位
substring(n,m):截取的是字符串中索引为n开始,为m结束,但不包括m这一项
slice(n,m):用法与substring相同,但可以支持负数索引
splice(n,m,item1,item2…):从第n个位置删除m个元素,包括第n个。添加item1,item2…新元素。会改变原数组,返回被删除的数组

//slice(n,m)
        var arr1 = [1,23,44,55,66,77,888,"fff"];
        var arr2 = arr1.slice(2,4) //从index为2截取到index为4之前不包括4
        console.log(arr2); //[44,55]
        console.log(arr1); // [1,23,44,55,66,77,888,"fff"]原始数组没有被改变

//splice(start,deleteCount,item1,item2)
        var arr3 = [1,2,3,4,5,6,7,"f1","f2"];
        var arr4 = arr3.splice(2,3) //删除第三个元素以后的三个数组元素(包含第三个元素)
        console.log(arr4); //[3,4,5];
        console.log(arr3); //[1,2,6,7,"f1","f2"]; 原始数组被改变

        var arr5 = arr3.splice(2,0,"wu","leon"); 
        //从第2位开始删除0个元素,插入"wu","leon"
        console.log(arr5); //[] 返回空数组
        console.log(arr3); // [1, 2, "wu", "leon", 6, 7, "f1", "f2"]; 原始数组被改变

        var arr6 = arr3.splice(2,3,"xiao","long");
        //从第2位开始删除3个元素,插入"xiao","long"
        console.log(arr6); //["wu", "leon", 6]
        console.log(arr3); //[1, 2, "xiao", "long", 7, "f1", "f2"]

        var arr7 = arr3.splice(2);//从第三个元素开始删除所有的元素
        console.log(arr7);//["xiao", "long", 7, "f1", "f2"]
        console.log(arr3); //[1, 2]

  1. this的指向情况
  1. 全局作用域中的函数:非严格模式下其内部this指向window;
  2. 对象内部的函数:其内部this指向对象本身;
  3. 构造函数:其内部this指向生成的实例;
  4. 由apply、call、bind改造的函数:其this指向第一个参数;
  5. 箭头函数:箭头函数没有自己的this,看其外层的是否有函数,如果有,外层函数的this就是内部箭头函数的this,如果没有,则this是window。(函数定义时的this,而不是调用时this)
  1. 宏任务和微任务
  1. 宏任务和微任务是什么?
    由于js是一种单线程语言,在任务多的情况下就有了同步和异步任务。在es5之后,javascript自身能引起异步请求的能力,这时就产生了宏任务和微任务。
  2. 宏任务和微任务分别有哪些?
    宏任务(由宿主发起):setTimeout/setInterval;script外层同步代码…
    微任务(由js引擎发起):promise;proxy;…
  3. 宏任务和微任务执行顺序?
    先执行同步任务 —>在执行异步任务 ( 先执行异步微任务—> 再执行异步宏任务 )
  1. cookie、sessionStorage,localStorage区别

一、html5 web本地存储:sessionStorage和localStorage。
以键值对的形式存储,通常以字符串存储,存储复杂类型时,需要进行数据格式转换。
不参与服务器的通信,仅存在客户端。

  1. localStorage:生命周期为永久,除非手动清除localStorage,否则信息一直都在。
  2. sessionStorage:生命周期为当前会话,关闭浏览器或关闭页面后被清除。

二、cookie:简言之,cookie是服务器端发给客户端的文本文件;目的是用于辨别用户身份。
如果不在浏览器中设置过期时间,cookie被保存在内存中,生命周期随浏览器的关闭而结束,这种cookie简称会话cookie。
如果在浏览器中设置了cookie的过期时间,cookie被保存在硬盘中,关闭浏览器后,cookie数据仍然存在,直到过期时间结束才消失。

  1. 数组排序的方法
  1. Array.sort()函数
			var ary = [311,43,54,4,40,26,31,33]
			var arySortA = ary.sort();
			console.log(arySortA);//26, 31, 311, 33, 4, 40, 43, 54
			
			//降序排列
	        var arySortB = ary.sort(function(a,b){
				return b-a;
			})
			console.log(arySortB);//311, 54, 43, 40, 33, 31, 26, 4
  1. 冒泡排序
    原理:a.比较相邻的元素,如果第一个比第二个大,就交换他们;
    b.对每一对相邻元素做同样的工作,最后的元素应该会是最大的数;
//判断是否是数组,数组是否为空
function arrisArray ( arr ) {
    return Object.prototype.toString.call(arr) === '[object Array]' && arr.length > 0 
// 如果是数组并且数组长度大于零,则返回true。
}

//封装冒泡排序函数
function bubble(arr){   
if(arrisArray(arr)){
    //外层循环,控制趟数,每一次找到一个最大值
    for (var i = 0; i < arr.length - 1; i++) {
        // 内层循环,控制比较的次数,并且判断两个数的大小
        for (var j = 0; j < arr.length - 1 - i; j++) {
            // 白话解释:如果前面的数大,放到后面(当然是从小到大的冒泡排序)
            if (arr[j] > arr[j + 1]) {
                //var temp = arr[j];
                //arr[j] = arr[j + 1];
                //arr[j + 1] = temp;
                [arr[i], arr[i+1]] = [arr[i+1], arr[i]]//使用结构赋值简洁代码
            }
        }
    }
       return arr  
 }
}
var arr = [29,45,51,68,72,97]; 
 console.log(bubble(arr));//[2, 4, 5, 12, 31, 32, 45, 52, 78, 89]
  1. 数组去重的方式

简单数组去重:

  1. Set()+Array.from()
    const result = Array.from(new Set(arr))
  2. 利用两层循环+数组的splice方法
  3. 利用数组的indexOf / includes方法
  4. 利用数组的filter()+indexOf()

数组对象去重:

1、对象访问属性的方法
//
let newArr = [];
    let obj = {};
    for (var i = 0; i < arr.length; i++) {
       if (!obj[arr[i].key]) {
         newArr.push(arr[i])
         obj[arr[i].key] = true
       }
    }
console.log(newArr);

2、Map()方法
//set方法设置key所对应的键值,然后返回整个Map结构。如果key已经有值,则键值会被更新,否则就新生成该键。
//values方法可以返回Map对象值的遍历器对象

let map = new Map();
for (let item of this.arr) {
    map.set(item.id, item);
 }
this.arr = [...map.values()];
console.log(this.arr)

3、reduce() 方法
//reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值
const obj = {}
arr = arr.reduce((total, next) => {
  obj[next.key] ? '' : obj[next.key] = true && total.push(next)
  return total
}, [])
console.log(arr)
  1. 闭包
  1. 什么是闭包?
    闭包可以当作一个密闭的容器,用来存储数据,它是一个对象,存放数据的格式:key:value。
  2. 闭包形成的条件?
    函数嵌套 并且 内部函数引用外部函数
  3. 闭包的应用场景?
    它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
  4. 闭包的优缺点?
    优点:延长外部函数局部变量的生命周期
    缺点:本应被销毁的变量,因为闭包的原因没有被销毁,长期存在的话,容易造成内存泄漏
  1. ES6新增了哪些特性
  1. 新增let const关键字
  2. 新增解构赋值和箭头函数
  3. 新增模块化,通过import导入 然后通过export导出
  4. 新增promise,es6处理异步的一种方。本质是一个对象,promise的参数是一个回调,回调有连个参数 resolve 成功回调 reject 失败回调。
  1. post和get请求的区别
  1. get因为参数会放在url中,所以隐私性,安全性较差,请求的数据长度是有限制的,不同的浏览器和服务器不同,一般限制在 2~8K 之间,更加常见的是 1k 以内。get请求一般是去取获取数据。
  2. post请求是没有的长度限制,请求数据是放在body中。post请求一般是去提交数据。
  3. get请求可以被缓存,post请求不会被缓存。get请求会被保存在浏览器历史记录当中,post不会。get请求可以被收藏为书签,因为参数就在url中,但post不能,它的参数不在url中。
  1. RESTful 风格
  1. 通过http GET/POST/PUT/DELETE 获取/新建/更新/删除 资源
  2. 一般使用JSON格式返回数据
  1. new一个对象的过程发生了什么
  1. 创建空对象
  2. 新对象执行prototype连接原型
  3. 绑定this到新对象上
  4. 执行构造函数
  5. 返回新对象
  1. ES6中的 class

Class是面向对象的语法的一个实现。Class本质上类似一个模板,通过模板去构建一些东西。可以通过constructor去构建一些东西,构建的时候可以复制一些属性,一些方法。

//类 开头大写
class Student {
    //构造器构造属性
    constructor(name,number) {
        //this代表当前你正在构造的实例
        this.name = name;
        this.number = number;
    }
    //方法
    sayHi() {
        console.log(`姓名 ${this.name}, 学号 ${this.number}`)
        // console.log('姓名 ' + this.name + ' , 学号' + this.number)
    }
}
//通过类 new 对象/实例   
const xialuo = new Student('夏洛', 100)
console.log(xialuo.name);//夏洛
console.log(xialuo.number);//100
xialuo.sayHi();//姓名 夏洛, 学号 100

class的继承:有很多个class,这些class有一些共用的属性的时候,就可以抽离出来。

  1. 通过extends去做的
  2. 里面通过super来执行父类的构造函数,也就是父类的构建过程。
  3. 扩展或重写的方法
//父类
class People {
    constructor(name) {
        this.name = name
    }
    eat() {
        console.log(`${this.name} eat something`)
    }
}

//子类 继承父类 里面的方法可以直接调用,属性需要调用super去执行
class Student extends People {
    constructor(name,number) {
        //调用super,People会自动帮我们处理name
        super(name)
        //自己处理,学生才有自己的学号
        this.number = number
    }
    sayHi() {
        console.log(`姓名 ${this.name} 学号 ${this.number}`)
    }
}

//子类
class Teacher extends People {
    constructor(name,major) {
        super(name)
        this.major = major
    }
    teach() {
        console.log(`${this.name} 教授 ${this.major}`)
    }
}

//实例
const xialuo = new Student('夏洛', 100)
console.log(xialuo.name);//夏洛
console.log(xialuo.number);//100
xialuo.sayHi();//姓名 夏洛 学号 100
xialuo.eat();//夏洛 eat something

//实例
const wanglaoshi = new Teacher('王老师','语文')
console.log(wanglaoshi.name);//王老师
console.log(wanglaoshi.major);//语文
wanglaoshi.teach();//王老师 教授 语文
wanglaoshi.eat();//王老师 eat something
  1. var、 let、 const 的使用区别
    被面试官问的那些高频面试题---web前端_第2张图片

三、CSS

  1. 用div画一个三角形

div{        /*宽高为0*/
            width: 0;
            height: 0;
            /*在三角形一边设置一个边界颜色*/
            border-top: 20px solid red;
            /*其它3边设置相同颜色,*/
            border-bottom: 20px solid white;
            border-left: 20px solid white;
            border-right: 20px solid white;
  1. 盒子居中的 方法

1、绝对定位居中
2、负margin居中
3、margin固定宽高居中
4、flex居中
5、transform居中
6、不确定宽高居中(绝对定位百分数:只需要保证left和right的百分数一样就可以实现水平居中,保证top和bottom的百分数一样就可以实现垂直居中。)

  1. CSS盒子模型的理解
  1. css盒子模型 ,包含了元素内容(content)、内边距(padding)、边框(border)、外边距(margin)几个要素。
  2. box-sizing中比较常用的两个属性值为
    1). content-box :标准盒子,默认模式
    盒子的宽度=margin(左右外边距)+padding(左右内边距)+border(左右边框)+内容的(width).
    2). border-box:怪异盒子
    盒子的宽度=内容的(width)+margin(左右)(这里的内容width包含了padding(左右内边距)+border(左右边框))
  1. 清除浮动的方式
  1. 额外标签法: 给谁清除浮动,就在其后额外添加一个空白标签。
    优点: 通俗易懂,书写方便。(不推荐使用)
    缺点: 添加许多无意义的标签,结构化比较差。
  1. 父级添加overflow方法: 可以通过触发BFC的方式,实现清楚浮动效果。必须定义width或zoom:1。同时,不能定义height,因为使用overflow:hidden时,浏览器会自动检查浮动区域的高度。
    优点: 简单、代码少、浏览器支持好。
    缺点: 内容增多时候容易造成不会自动换行导致内容被隐藏掉,无法显示需要溢出的元素。不能和position配合使用,因为超出的尺寸的会被隐藏。
  1. 使用after伪元素清除浮动
    优点: 符合闭合浮动思想,结构语义化正确,不容易出现怪问题(目前:大型网站都有使用,如:腾迅,网易,新浪等等)
  1. 使用before和after双伪元素清除浮动
  1. flex布局(弹性布局)

注意:设为Flex布局后,子元素的float、clear和vertical-align属性将失效。

子元素设置的属性
flex属性是flex-grow(放大比例), flex-shrink(缩小比例) 和 flex-basis的合写,默认值为0 1 auto;
align-self属性(单独给自己设置对齐方式)

  1. 什么是BFC以及触发条件
  1. BFC:块级格式化上下文,BFC是一块块独立的渲染区域,可以将BFC看成是元素的一种属性,拥有了这种属性的元素就会使他的子元素与世隔绝,不会影响到外部其他元素。
  2. 触发BFC:
    ·设置浮动,不包括none
    ·设置定位,absoulte或者fixed
    ·行内块显示模式,inline-block
    ·设置overflow,即hidden,auto,scroll
    ·表格单元格,table-cell
    ·弹性布局,flex
  3. 解决问题:
    1)解决外边距的塌陷问题(垂直塌陷)
    2)顶部包含塌陷
    3)清除浮动 overflow:hidden
  1. 行内元素、块级元素、行内块元素

常见行内元素:span、a、i、br
常见块级元素:div、p、ul、li、form、table、h1~h6
常见行内块元素:img、input

  1. css中的选择器及其权重

!important =》无穷
行类样式 =》 1000
ID选择器 =》0100
类选择器,伪类选择器=》0010
元素选择器 =》0001
css继承 =》0000

四、其他

1)、 git

详细参考: http://t.csdn.cn/Mpw7B

  1. 用git工具检查当前状态
  2. 查看当前分支命令
  3. 代码误删,怎么恢复?
    本地项目还在的情况下,在有.git的那个目录下载,打开bash窗口,输入命令git reflog。窗口里面会展示从建立以来所有的变动log日志,找到想要的版本。
    使用q键退出检视,接着输入git checkout -b 新分支名字 HEAD@{编号} 命令。

2)、TCP协议

TCP协议是对数据传输提供的一个管控机制
详细面试题参考: http://t.csdn.cn/YQbOY

3)、WebSocket

  1. 什么是WebSocket?
    WebSocket是HTML5下一种新的协议,是一个持久化的协议(本质上是一个基于tcp的协议)。
    它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯的目的。
  2. Websocket解决的问题?
    解决了Http长连接传统的客户端对服务器发起请求的模式,实现客户端与服务器端完全平等,解决了http不能实时更新的弊端。

4)、情景题

  1. 使用promise实现一个异步下载函数,下载完毕给出提示弹框

  1. 定义一个匿名函数和箭头函数
//匿名函数的this指向window。
//在使用时:可以当做变量的值、当做参数值、可以自调用
function show4(){
            let m = function(){
                console.log('key');//key
            }
            m();
        }
        show4();
//箭头函数的this指向要调用函数的对象
//在使用时:可以当做变量的值、当做参数值、可以自调用
  function show4() {
            let test = (name, age) => {
                console.log(name, age);//wang 20
            };
            test('wang', 20);
        }
        show4();

你可能感兴趣的:(web前端,javascript,vue.js,面试,前端)