前端面试题

123 阅读7分钟

html

css

js

1.js的数据类型有哪些

字符串string 数字 number 布尔bool undefined null 大整数 bigint 符号 symbol 对象 object

2.原型链是什么

数组对象 a =[]

b=Array.prototype

c=Object.protptype

a._?__ === b

b._?__ === c

a ===> b ===> c

怎么改: 只要改写x的隐藏属性,就可以改变x的原型


const x = Object.create(原型)

const x = new 构造函数()

es5没有class,es6推出class

var a =new Array(1,2,3)

a.length是实例化

a.valueof是继承

原型链解决了什么问题:

原型链在没有class下实现继承

  1. a是Array的实例,a拥有Array.prototype里的属性
  2. Array继承了Object 3.a是Object的间接实例,a拥有Object.prototype a既有Array.prototype里的属性,又有Object.prototype里的属性

原型链的缺点:不支持私有属性

3.代码中的this是多少

this 是call的第一个参数
f1()   f1.call(undefined)
obj.child.method(p1,p2)  obj.child.method.call(obj.child,p1,p2)  

4.new做了什么

创建临时对象
绑定原型
执行构造函数
返回临时对象

5.什么是立即执行函数

是什么

声明一个匿名函数,然后立即执行它 怎么做


(function () {alert('我是匿名函数')} ())
(function () {alert('我是匿名函数')} )(

解决了什么问题

在es6之前,只能通过它来创建局部作用域

优点

兼容性好

怎么解决缺点: 使用ES6的block +let 语法

{
let a = '我是局部变量'
console.log(a)  //能读取a
}
console.log(a)  //找不到a

6.什么是闭包

闭包 是js 的一种语法特性

闭包 = 函数 + 自由变量 对于一个函数来说,变量分为 全局,本地,自由变量

{
  let count
 function add(){ //访问了外部变量的函数
  count +=1
	}
}
const add2 =function(){
  var count
 return function add(){
  count +=1
	}
}()

解决了什么问题

1.避免污染全局环境 2.提供对局部变量的间接访问 3.维持变量,使其不被垃圾回收

缺点 闭包 使用不当 可能造成内存泄漏

7.如何实现类

es5 没有 class

方法一

 function Dog(name){ 
 this.name = name
 this.legNumber = 4
 }
 Dog.prototype.kind = '狗'
  Dog.prototype.say = function(){
   console.log(${name},${this.legsNumber})
  }
   Dog.prototype.run = function(){
    console.log(${this.legsNumber})
   }
   const d1 =new Dog('')
   d1.ay()

方法二


class Dog{
    construor(name){
    this.name =name
    this.legsNumber =4
    }
    say(){
       console.log(${name},${this.legsNumber})
    }
    run(){
       console.log(${this.legsNumber})
    }
}

  const d1 =new Dog('')
   d1.ay()

8.如何实现继承

方法一:使用原型链


function Animal (legsNubmer){
	this.legsNumber = legsNumber
}
Animal.prototype.kind = '动物'

function Dog (name ){
	this.name =name
Animal.call(this , 4)
}
Dog.prototype._proto_ =Animal.prototype

Dog.prototype.kind = '狗'

Dog.prototype.say = function(){
    console.log( 汪汪汪, 我是${this.name},我有${this.legsNubmer}条腿。)
	}
  const d1 =new Dog('小哈')
  console.dir(d1)
  

方法二:使用class


class Animal{
    constructor(legsNumber){
	this.legsNumber =legsNumber
	}
	run(){}
}
class Dog extends Animal{
	 constructor(name){
	super(4)
	this.name =name
	}
      say(){
	  console.log( 汪汪汪, 我是${this.name},我有${this.legsNubmer}条腿。)
	}

}


9.手写节流防抖

节流


//节流就是 技能冷却中
const thrittle = (fn , time)=>{
	let 冷却中 = false
 	return (...args)=>{
	if(冷却中) return
	fn.call(undefined, ...args)
	冷却中 = true
	setTimeout(()=>{
	冷却中 = false
         },time)
	}
}
     //还有一个版本是在冷却结束时调用fn
     //简洁版 删掉冷却中变量,直接使用timer代替

const thrittle = (f , time)=>{
	let timer = null
 	return (...args)=>{
	if(timer) {return}
	f.call(undefined, ...args)
	timer =setTimeout(()=>{
	timer = null
         },time)
	}
}

防抖



//防抖就是 回城被打断
 const debounce = (fn,time)=>{
    let 回城计时器 = null
   return (...args)=>{
	if(回城计时器 ! =null){
	clearTimeout(回城计时器) //打断回城
	}
	//重新回城
回城计时器 =setTimeout(() =>{
	fn.call(undefined, ...args)//回城后调用fn
	回城计时器 = null
	},time)
     }
}

10.手写发布订阅

11.手写ajax

DOM

HTTP

必考:HTTP 状态码知道哪些?分别什么意思?

  • 2xx 表示成功
  • 3xx 表示需要进一步操作
  • 4xx 表示浏览器方面出错
  • 5xx 表示服务器方面出错

大公司必考:HTTP 缓存有哪几种?

  • 需要详细的了解 ETag、CacheControl、Expires 的异同

  • 答题要点:

    1. ETag 是通过对比浏览器和服务器资源的特征值(如MD5)来决定是否要发送文件内容,如果一样就只发送 304(not modified)
    2. Expires 是设置过期时间(绝对时间),但是如果用户的本地时间错乱了,可能会有问题
    3. CacheControl: max-age=3600 是设置过期时长(相对时间),跟本地时间无关。

必考:GET 和 POST 的区别

GET 用于获取资源,POST 用于提交资源。

Cookie V.S. LocalStorage V.S. SessionStorage V.S. Session

  • Cookie V.S. LocalStorage
1.  主要区别是 Cookie 会被发送到服务器,而 LocalStorage 不会
1.  Cookie 一般最大 4k,LocalStorage 可以用 5Mb 甚至 10Mb(各浏览器不同)
  • LocalStorage V.S. SessionStorage

    1. LocalStorage 一般不会自动过期(除非用户手动清除),而 SessionStorage 在回话结束时过期(如关闭浏览器)
  • Cookie V.S. Session

    1. Cookie 存在浏览器的文件里,Session 存在服务器的文件里
    2. Session 是基于 Cookie 实现的,具体做法就是把 SessionID 存在 Cookie 里

框架 Vue

必考:watch 和 computed 和 methods 区别是什么?

watch :监听数据 computed:计算属性

  1. computed 和 methods 相比,最大区别是 computed 有缓存:如果 computed 属性依赖的属性没有变化,那么 computed 属性就不会重新计算。methods 则是看到一次计算一次。
  2. watch 和 computed 相比,computed 是计算出一个属性(废话),而 watch 则可能是做别的事情(如上报数据)

必考:Vue 有哪些生命周期钩子函数?分别有什么用?

beforeCreate:创建组件之前

created:创建组件之后

beforeMount:挂载组件之前

mounted: 挂载组件之后 数据请求

beforeUpdate:更新之前

updated:更新之后

beforeDestroy:组件毁灭之前

destoryed:组件毁灭之后

  1. 把名字翻译一遍就是满分
  2. 要特别说明哪个钩子里请求数据,答案是 mounted

必考:Vue 如何实现组件间通信?

父子组件:使用 v-on 通过事件通信 爷孙组件:使用两次 v-on 通过爷爷爸爸通信,爸爸儿子通信实现爷孙通信 任意组件:使用 eventBus = new Vue() 来通信,eventBus.oneventBus.on 和 eventBus.emit 是主要API 任意组件:使用 Vuex 通信

必考:Vue 数据响应式怎么做到的?

要点 使用 Object.defineProperty 把这些属性全部转为 getter/setter Vue 不能检测到对象属性的添加或删除,解决方法是手动调用 Vue.set 或者 this.$set

必考:Vue.set 是做什么用的?

添加或删除对象属性

Vuex 你怎么用的?

背下文档第一句:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 说出核心概念的名字和作用:State/Getter/Mutation/Action/Module

VueRouter 你怎么用的?

背下文档第一句:Vue Router 是 Vue.js 官方的路由管理器。 说出核心概念的名字和作用:History 模式/导航守卫/路由懒加载 说出常用 API:router-link/router-view/this.router.push/this.router.push/this.router.replace/this.route.paramsthis.route.params this.router.push('/user-admin') this.$route.params

路由守卫是什么?

看官方文档的例子,背里面的关键的话

Webpack

必考:有哪些常见 loader 和 plugin,你用过哪些?

file-loader:把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件 url-loader:和 file-loader 类似,但是能在文件很小的情况下以 base64 的方式把文件内容注入到代码中去 source-map-loader:加载额外的 Source Map 文件,以方便断点调试 image-loader:加载并且压缩图片文件 babel-loader:把 ES6 转换成 ES5 css-loader:加载 CSS,支持模块化、压缩、文件导入等特性 style-loader:把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS。 eslint-loader:通过 ESLint 检查 JavaScript 代码

define-plugin:定义环境变量 commons-chunk-plugin:提取公共代码 uglifyjs-webpack-plugin:通过UglifyES压缩ES6代码

英语题:loader 和 plugin 的区别是什么?

Loader直译为"加载器"。Webpack将一切文件视为模块,但是webpack原生是只能解析js文件,如果想将其他文件也打包的话,就会用到loader。 所以Loader的作用是让webpack拥有了加载和解析非JavaScript文件的能力。 Plugin直译为"插件"。Plugin可以扩展webpack的功能,让webpack具有更多的灵活性。 在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。

必考:如何按需加载代码?

Element出品的babel-plugin-component

必考:如何提高构建速度?

多入口情况下,使用CommonsChunkPlugin来提取公共代码

通过externals配置来提取常用库

利用DllPlugin和DllReferencePlugin预编译资源模块 通过DllPlugin来对那些我们引用但是绝对不会修改的npm包来进行预编译,再通过DllReferencePlugin将预编译的模块加载进来。

使用Happypack 实现多线程加速编译

使用webpack-uglify-parallel来提升uglifyPlugin的压缩速度。 原理上webpack-uglify-parallel采用了多核并行压缩来提升压缩速度

使用Tree-shaking和Scope Hoisting来剔除多余代码

转义出的文件过大怎么办?