前端面试题

261 阅读8分钟

1.Js基础

js的数据类型有哪几种,怎么判断属于何种类型

  • js的数据类型主要分为两大类:

    基本数据类型(原始数据类型)引用数据类型

    基本数据类型主要包括以下几种:

    number string boolean null undefined symbol

    引用数据类型主要包括以下几种:

    Object

    基本数据类型与原始数据类型的区别:

    首先基本数据类型存储的都是值,是没有函数可以调用的,比如:

引用数据类型存储的是地址也就是所谓的指针。
由于两者的存储方式不同,所以导致在变量之间的赋值也就有很大的差别,基本数据类型之间的赋值直接是值的拷贝,值改变时互不影响,引用数据类型之间的赋值是地址之间的指向,值改变时相互影响。如:

为了解决引用类型赋值之间的相互影响可以使用浅拷贝和深拷贝来解决这个问题
浅拷贝深拷贝的区别:
浅拷贝只能拷贝一层,当第二层为引用数据类型就不能实现了。
深拷贝可以拷贝多层。

类型的判断可以使用 typeof 或者 instanceof

Typeof 与 instanceof 都不能正确的判断数据类型,typeof可以判断基本数据类型(null除外),instanceof可以判断引用数据类型(实现原理是通过原型链)
  • 类型转换

详解见

  • this

  • == 与 ===

对于 == 来说,具有隐士类型转换的功能

思考

[] == ![] 
  • 闭包及作用域

    通俗来说就是函数中嵌套函数,在嵌套的函数里面能够访问到外面函数里的变量。

思考

function fun(n, o) {
  console.log(o);
  return {
    fun: function (m) {
      return fun(m, n)
    }
  }
}
var a = fun(0);
a.fun(1);
a.fun(2);
a.fun(3);
var b = fun(0).fun(1).fun(2).fun(3);
var c = fun(0).fun(1);
c.fun(2);
c.fun(3);
  • 原型及原型链

原型

原型主要通过prototype字段来体现,prototype指向原型对象。
如:数组的原型

如: 对象的原型

我们使用的数组,对象的方法也都是来自于原型。
我们可以在数组中的原型中添加一个一维数组(纯数字)的求和方法  如下:

```
Array.prototype.sum = function() {
	let sum = 0
	this.forEach(item => sum += item)
	return sum
}

let arr = [1, 2, 3]
arr.sum() 	// 6
```

原型的优点: 解决构造函数中共有方法重新定义的,节省内存。

function Person(name)  {
	this.name = name
}

Person.prototype.getName = function() {
	console.log(this.name)
}

let p1 = new Person('李四')
p1.getName()	// 李四
let p2 = new Person('张三')
p2.getName()	// 张三

console.log(p1.getName === p2.getName)	// true

原型链

原型链主要就是通过__proto__属性连接起来的。

图解:

  • 单线程及异步

    什么是单线程,js为什么是单线程的?

    单线程简单来说同一时间只能做同一件事情,两段js不能同事执行(但是在H5中有Web Workers 可以开启多个线程,不能操作dom)。 Js是单线程的原因是,避免dom渲染时的冲突(如: 当前线程在操作某dom,其它线程却把当前dom给删了,这样就出现问题了)。

    单线程带来了什么问题?怎么解决?

    单线程带来了等待执行的问题(两段js代码不能同时执行),如延时器。为了解决这个问题就有了异步。

    异步是如何实现的?带来了什么问题?怎么解决?

    异步的实现原理是event-loop(事件轮询)

所在的问题:
1:代码没有按照顺序执行
2:callback函数内的代码不利于模块化
Promise 或者 async/await 来解决

2.Es6

es6必须要通过babel解析成es5之后才能运行(基于chrom内核的除外)

  • var let const 之间的区别

    var 能重复定义,可以修改,没有块级作用域,只有函数作用域,具有变量提升能力

    let 不能重复定义,可以修改,具有块级作用域,没有变量提示

    const不能重复定义,不可以修改,具有块级作用域,没有变量提示

    var在全局作用域下声明变量会导致变量挂载在 window上,其他两者不会

    注意函数也有提升的能力,并且还是提升整个整体

思考

console.log(a)
function a() {}
var a = 1
  • Class

Class 只是一种语法糖,本质还是构造函数。Class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已

  • 模块化

使用模块化的好处:

提高代码的复用率

解决命名冲突

提升代码的可维护性

语法 导入:import 导出:export 或者 export default

  • Promise

为了解决传统异步回调所以有的代码都写在同一个回调函数里面(可读性差,不利于封装),Promise可以实现链式操作还可以分步处理(串行)。

Promise的执行流程:

  • async/await (es7)

将代码同步化,可读性高,去除了回调函数。

虚拟Dom

  • 什么是虚拟Dom? 有什么作用?

用js大至实现dom树,因为dom操作非常‘昂贵’,将dom对比放在js层来做提高效率,减少dom的操作(diff算法实现)。

  • 虚拟Dom的使用,核心api?

虚拟dom的使用可以参考snabbdom,主要有两个api,h函数生成虚拟node,patch函数有两种作用,第一种:直接挂载到真的dom节点下,第二种:对比新旧虚拟dom然后局部更新真实dom。

  • 简单介绍diff算法

diff算法是linux的基本命令,主要比较两个文本之间的不同之处。使用diff算法主要是找出两个节点之间的不同之处然后局部渲染真实的dom。

4.MVVM与Vue

  • MVC

什么是MVC?

M:Model 数据模型

V: View视图

C:Controller 控制器(逻辑处理)

MVC 主要用户服务端如node 的 express 框架。

  • MVVM

什么是 MVVM ?

M:Model 数据模型

V:View 视图(数据与视图分离)

VM:ViewModel 连接视图与数据模型

MVVM 并不是一个新的概念,只是从 MVC 上演变过来的适合前端使用的一套标准。ViewModel 算是一个小的创新。Vue 是典型的一个 MVVM 模式的框架。

Vue

  • Vue 与 Jquery 的区别?

    1:数据视图分离

    2: 数据驱动视图

  • Vue 的三大要素?

    1: 响应式

2: 解析模版

3: 渲染

响应式

Vue 的响应式原理主要通过 Object.defineProperty()来实现,将 data 中的属性及 methods 中的方法代理到 vm 实例中。
Object.defineProperty 函数解析:

第三个参数的属性见

模版引擎

什么是模版?

Vue 中的模版其本质就是一个字符串,该字符串中含有逻辑处理,格式与 html 一样,最终需要解析成 html 来执行。

解析过程:

先解析析成 js 代码也就是 render 函数,最后 render 函数返回一个虚拟dom,最后通过 patch 函数渲染成真是的 dom 

渲染

首次渲染,通过updateComponent方法执行vm._render函数(会访问到vm实例上的属性,get 方法监听到(绑定依赖)),最终返回vdom,最后通过patch 函数渲染成dom

改变vm 实例(必须是监听了get 方法的属性)上面的属性时,set 方法监听到,set 方法会执行 updateComponent 方法,在调用vm._render 方法生成新的vdom, 最后调用patch函数渲染成dom。

组件化 与 React

  • 组件化

什么是组件化?

组件化主要的思路就是一个页面分多个模块来处理,使其各个模块互不影响(React 变现最佳)。

组件化表现为:封装,复用。

封装:主要体现为视图,数据,业务逻辑的封装。

复用:考虑外部使用者需要什么功能,内部需要向外部暴露什么接口(也就是props传值)

组件化的好处

  1. 降低了代码的冗余度
  2. 降低了代码的联动性
  3. 提高了代码的复用率
  4. 提高了代码的可读性
  • React

什么是jsx

语法:跟html语法类似,但是不同之处在于jsx可以执行js。(遇到尖括号解析成html,遇到大括号解析成js。) jsx本身已成为一种标准,其实也是一种语法糖,最后jsx还是会转化成js(React.createElement())来运行,最终js在转化成html给浏览器引擎来渲染。

为什么需要用到vdom

因为jsx 会被解析成html,数据驱动视图的变化,而不是直接操作dom

何时patch

ReactDom.render()与setState时触发patch函数

setState为什么是异步的?

setState与vue修改属性都是异步的。原因:避免用户连续修改同一变量的值,导致多次渲染带来的性能问题。

Vue与React

  • 不同点

1: 本质区别

Vue 属于MVVM框架,由MVC发展而来
React 属于组件化框架

2: 模版区别

Vue 使用的是模版,本质就是一个字符串
React 使用的JSX,JSX已经成为了一个标准

3: 组件化的区别

Vue 的组件化是从MVVM上扩展的
React 本身就是组件化的
  • 相同点

    1: 数据视图分离

    2: 数据驱动视图的变化

    3: 都支持组件化编程

    总结:Vue 的学习成本较低,文档清晰已读,国内社区活跃度高。 React 文档英文化读起来有一定难度,国内社区相对活跃度较低。

谢谢阅读,有错误之处,敬请指教。