2020 前端面试题Go Go Go

js中有哪些数据类型

六种原始数据类型

  • Boolean 有两个值true和false
  • Number 数字
  • String 字符串
  • Null 值为null,指对象的值没有设置
  • Undefined,没有被复制的变量会有一个默认值undefined
  • Symbol 符号,定义了之后就不能被修改

引用类型 Object

js中判断数据类型的方式

  • typeof 返回一个字符串,表示数据类型
  • instanceof 判断A是否是B的实例

undefined和null的区别

变量被声明但是没有赋值,等于undefined

调用函数的时候需要填参数,但是没有传递,这个时候就是undefined

对象没有赋值的属性,undefined

函数没有返回值,默认是undefined

js中数组的常见方法

find 根据条件查询符合条件的一条记录

findIndex 根据条件查询符合条件的数据的索引

indexOf 返回的是元素所在的位置

filter 过滤,返回一个符合条件的数组

map 遍历原始数据,生成一个新的数组,新数组的长度和原数组一致 新数组中的每一项是map循环的返回值

forEach 遍历数组

reduce 对数组做聚合操作,返回一个结果

sort 排序

splice 替换或者删除元素

字符串的操作

indexOf 判断是否包含指定的子串

startsWith 以什么开始

substr 截取

substring 截取

replace 替换

深拷贝和浅拷贝的问题

浅拷贝值复制对象的第一层,如果对象的属性中还是对象那就没办法实现复制

深拷贝就是逐层对对象的所有结点做拷贝复制,最简单常用的实现方式JSON.parse(JSON.stringify(目标对象)),这种方式有一个缺点,只能实现符合标准JSON数据格式的内容

闭包

闭包就是能够读取其他函数内部变量的函数

在js中函数外部是无法直接读取函数内部的变量,但是内部是可以直接读取外部变量

用法

  • 读取函数内部的变量
  • 让变量的值始终保存在内存中,形成一个局部独立的作用空间

需要注意

由于闭包会使得函数中的变量被保存在内存,内存占用率会比较高,尽量避免不要随意使用闭包,容易导致内存泄漏

js中一些特殊的数据类型使用

true 是1

false 是0

NaN 不是数字

Math数学函数

Math.abs 求绝对值

Math.ceil 向上取整

Math.floor 向下取整

Math.random 随机数,范围是 0=<x<1

Math.pow 一个数字的多少次方 Math.pow(3, 4) 相当于 3x3x3x3

四舍五入操作

保留两位小数

var num = 9.09870912;
console.log(num.toFixed(2)); // 四舍五入
console.log(Math.floor(num * 100) / 100); // 保留两位小数
console.log(Number((8.897).toString().match(/^\d+(?:\.\d{2})?/))); // 正则表达式方式

Object对象的操作

获取对象中所有的属性名
// for in // 循环对象的所有属性名
// Object.keys // 返回一个数组
// {"1": "Tom", "1-2": "Jerry", "3": "Tim"} // 在js中如果属性名比较特殊,可以使用类似数组下标的形式获取属性值,把属性名当作下标

事件传播流程

三个阶段,捕获阶段->目标阶段->冒泡阶段

捕获阶段是从html标签的最外层开始传递,到触发事件的标签为止

目标阶段指在触发事件的标签之上进行传递,在其上的传递是和添加的先后顺序有关系的

冒泡阶段从触发事件的标签开始,逐层往外进行传递直到html标签为止

onXX 添加的是冒泡阶段触发的事件

addEventListener 有第三个参数,是一个bool值,默认是false表示在冒泡阶段触发

事件传播流程的阻止

stopImmediatePropagation 立即阻止事件的传播,其后的所有流程都不在继续执行

stopPropagation 阻止事件的传播,不会停止当前标签的传递,不会往后继续传递

onXX和addEventListener的区别

onXX添加事件的时候属于标签的属性赋值,只能设置一次,后面的属性值设置之后会覆盖掉前面

addEventListener又叫事件委托,可以添加多个,每一个都会执行

event中的target和currentTarget有什么区别

target表示触发事件的标签

currentTarget表示绑定事件的标签

js中的代码执行顺序

匿名函数

没有名字的函数就是匿名函数

匿名函数的自调用

// 匿名函数的自调用
(function () {
    console.log("111");
})();
概念

js是单线程,遇到一些比较耗时的操作时,一般使用异步进行处理

同步:又叫阻塞模式,上一步的代码执行完成之后会继续往后执行

异步:非阻塞模式,当代码执行成功之后会调用回调函数

js中的事件循环:

js是单线程的,只有一个线程可以干活。我们所有的操作都需要一步一步进行。

同步任务

异步任务,异步任务会进入一个异步队列,先不执行。等所有的同步任务完成之后,再去查看异步队列中的内容

这个过程是不断重复的,直到所有的任务都执行完

Event Loop

  • 微任务:Promise,process.nextTick
  • 宏任务:script,setTimeOut,setInterval
setTimeout

延迟执行,过一段事件之后执行。如果在页面中使用了很多之后,实际的执行时间可能会超过我们设置的时间,因为它是异步任务,所以需要等同步任务完成之后在执行,如果同步任务特别多,等待时间就会相应的延长。会等主线程中的所有任务都完成之后再执行

setInterval

固定的时间间隔之后重复执行代码。和setTimeout一样,需要等待同步任务执行完成之后再执行

setInterval存在一些问题,使用了之后会引起cpu占用率高,这个问题如何解决?

requestAnimationFrame可以解决这个问题,它是按照浏览器的刷新频率进行执行的,每秒钟执行60次,再浏览器每一次重绘的时候会执行回调函数

js中的流程控制语句

if else/ switch case

js中的循环语句

for(var i =0;i<10;i++){
    //
}
// while
// do while

js中的代码调试

可以直接使用浏览器打开source源码,加断点进行调试

console.xx 再浏览器的调试窗口输出内容

  • console.log
  • console.group和console.groupEnd
  • console.info
  • console.warn
  • console.error

浏览器中常用的调试工具和技巧

this指向

在js中这个问题很重要

this指向遵循一个原则:this永远指向函数运行时所在的对象

改变this指向
  1. 定义一个变量that暂存一下this
  2. 使用箭头函数,它的this是指向当前调用的环境
  3. bind,call和apply

默认的this是指向window,在严格模式中this指向null

原生对象和宿主对象

原生对象是ECMAScript规定的对象,所有的内置对象都是原生对象,比如Array、Date、Bool值等

宿主对象是宿主环境的对象,比如浏览器中的Document、window

什么是事件委托/代理

事件委托是利用事件的冒泡特性(事件的传播流程),将本应该绑定在多个元素上的事件绑定到他们的父元素上,动态添加标签的时候绑定事件可以使用事件委托的方式。这样做的好处是提高程序的性能、减少内存空间的浪费

变量声明提升

通过var顶的变量会被提升至作用域的顶端

document.onload和document.ready有什么区别

ready表示dom结构加载完成,不包含音视频和图片资源

onload表示所有的资源和dom结构加载完成

js中的本地存储技术有哪些?他们有什么区别

localStorage

sessionStorage

cookie

localStorage和sessionStorage是本地存储,他们能够存储的大小可以达到5m,

localStorage存储时间永久除非手动删除,否则一直在;sessionStorage存储时间是当前会话,关闭浏览器之后存储的数据消失。

他们都是只能存字符串,以键值对的形式进行存储

cookie存储大小不超过4k,cookie每一次和服务器交互的时候都会在http的请求头中进行传递

http常用的状态码

200	成功

301	重定向

401	未授权

403	没有权限访问目录

404	页面找不到,路径错误

50x	服务器内部错误

从输入网址到页面加载完成都发生了什么

  • dns解析
  • tcp连接
  • 发送http请求
  • 服务器处理请求并返回内容
  • 浏览器解析内容渲染页面
  • 结束连接

网站性能优化

  • 页面

    合并文件(css,js),减少http请求

    减少dom元素数量

    图片懒加载

  • 资源

    js、css、html文件压缩

    对图片资源做压缩

  • 网络

    cdn资源

    提高服务器的带宽

  • 服务器

    开启gzip压缩

    优化服务器性能

    优化代码的执行速度

url中的参数获取

http://www.xx.com/news?id=18&from=wechat

获取url中传递的参数

window.location.search 获取当前url中search值(?....)
var strSearch = window.location.search;
// 获取url中?后面的参数
function getUrlParam(name) {
    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
    var result = strSearch.substr(1).match(reg);
    return result ? decodeURIComponent(result[2]) : null;
}

// URLSearchParams可以用来获取url中的参数
//
function getUrlParam2(name) {
    var up = new URLSearchParams(strSearch);
    return up.get(name);
}
// 可以使用qs模块做url的解析和格式化
// https://cdn.bootcdn.net/ajax/libs/qs/6.9.4/qs.min.js
// Qs.parse(strSearch, {ignoreQueryPrefix: true}) // 把url中的search格式化为一个对象
//		{ id: 123, name: 'tom' }
// var obj = { name: 'Tim', age: 18, skills: 'power' }
// Qs.stringify(obj) // 可以把对象转换为url形式的字符串
//	"name=Tim&age=18&skills=power"

js中的垃圾回收机制

js中的内存管理是自动执行的,不可见的。我们创建变量、function等等需要使用内存。当一些不在需要使用的内容,js会自动的进行清除

没有被引用的对象就是垃圾,就需要被清除;js中检测并清除垃圾的时候使用一个标记清除算法

节流和防抖

节流

不停的执行一个操作,在指定的时间间隔内不会重复执行处理函数

当持续触发事件时,保证一定时间内只调用一次处理函数,意思是:假设用户一直触发这个函数,且每次触发时间间隔小于设定的值,在这个时间间隔内只调用一次

function throttle(fn, delay) {
    let valid = true;
    return function () {
        if (!valid) {
            // 在指定的时间间隔内
            return false;
        }
        valid = false;
        setTimeout(() => {
            fn();
            valid = true;
        }, delay);
    };
}
function showTop() {
    var scrollTop =
        document.body.scrollTop || document.documentElement.scrollTop;
    console.log("当前的滚动位置:" + scrollTop);
}
window.onscroll = throttle(showTop, 1000);
防抖

当持续触发事件时,一定时间段内没有再次触发事件,事件的处理函数会执行一次,如果设定时间到来之前,又触发了事件,就重新开始计时。也就是说当用户一致触发这个函数,并且时间间隔在设置好的时间内,那么防抖的情况下会只执行一次

function debounce(fn, delay) {
    let timer = null;
    return function () {
        if (timer) {
            clearTimeout(timer);
        }
        timer = setTimeout(fn, delay);
    };
}
function showTop() {
    var scrollTop =
        document.body.scrollTop || document.documentElement.scrollTop;
    console.log("当前的滚动位置:" + scrollTop);
}
window.onscroll = debounce(showTop, 1000);

=====有什么区别

== 是否相等

=== 恒等

== 两边的类型不同的时候,先进行类型转转,在比较

=== 不做类型转换,类型不同的一定不相等

===比较

如果类型不同,就不相等
如果类型相同,值也相等那么就相等;否则就不等

==比较

先进行类型转换在进行比较

if的条件

var k
if(k) {
    console.log(11)
} else {
    comsole.log(222)
}
// 输出222


var obj = {}
if(obj) {
    console.log(333)
} else {
    console.log(444)
}
// 输出333
小技巧
// 为变量设置默认值
var k // 定义一个k但不进行赋值
var b = k || 'a'
// 此时的b值为 'a'

k = 9
var c = k || 'abc'
// 此时的c值为 9

// 三元表达式
// bool?'为真的值':'为false的值'

js中的arguments是什么

在js中每个函数都会有一个Arguments对象的实例arguments,他便是函数接收的参数,可以用数组下边的方式获取arguments的数据

function sum(a, b) {
    console.log(arguments);
}
function sumArgs() {
    const [a, b, ...args] = arguments; // 解构赋值
    console.log(a);
    console.log(b);
    console.log(args);
}

严格模式

在代码前加上’use strict’就表示使用严格模式

同源策略

域名、协议、端口号一致的情况下叫同源

script、img、iframe的src属性,href不受同源策略影响

cors

cors(跨域请求资源共享),余姚在服务器的响应头中添加一句话Access-Control-Allow-Origin,请求当前域名的数据时就能进行跨域操作。在不同的web服务器中配置方式不一样

代理服务器

我们在开发的时候可以在本地启一个临时的服务器,做一个反向代理。

在浏览器中安装插件
websocket

允许跨域通信

jsonp

是利用了script标签不受同源策略影响的,相当于在页面中加入了一个script标签,通过src属性加载一个js文件。这个不能解决post请求的问题,此方案需要客户端和服务器端都修改代码

在实际工作中,所有的跨域问题都是服务器端解决的,前端解决不了跨域。vue或者react中配置的proxy代理是只在开发阶段才有效果,上线之后就没用了。因为他们相当于在本地起了一个代理服务器

http请求报文

请求行	请求方法 路径地址 协议的版本号
请求头
	host
	origin
	Content-Type

请求体
	实际传递的数据,请求体中的数据格式是由请求头中的Content-Type决定的

jQuery发送ajax请求

jQuery发送的ajax请求默认的请求头中的content-type为url编码格式的,请求体中的数据为:a=123&b=9&c=9

axios请求

axios默认的请求头中的content-type为json编码的,请求体中的数据为{ “a”: 1, “b”: 3 }

我们用代码发送请求的时候可以通过设置请求头中的content-type指定请求体中传递的数据是什么格式

回调函数(callback)

把一个function当作参数传递给另一个方法使用,当方法中的处理完成之后调用我们传递的参数

有点:解决了异步问题

缺点:回调地狱,不能使用try/catch,不能用return

Promise

Promise为了解决callbask的问题而产生的,Prmose是一个链式调用,每一次成功之后都会触发then回调,then返回的是一个新的Promise对象,可以继续then进行调用

const p = new Promise(function(resolve, reject) {
    // success
    reslove()
    // fail
    // reject
})

Promise.race 最快的一个Promise执行完成之后结束

Promise.all 所有的Promise执行完成之后结束,then里面的参数为没有一个Promise对象成功之后的返回值

我们在一个页面中同时发起20个请求,如何保证所有的请求按照我们发送的顺序全部执行完成?

Promise当状态改变之后就不可逆

async/await

async/await被称为异步的终极解决方案

优点:代码清晰,可以像写同步代码一样写异步操作,可以直接使用try/catch做异常捕获,解决了链式调用过长的问题

缺点:await将异步代码改造成同步代码,使用过多的时候有可能会降低效率

await必须放在async修饰的关键词内,await会等待Promise成功之后获取返回值赋值给变量

箭头函数

  • 不需要function关键字
  • 如果只有一行代码的话可以省略return
  • this指向当前上下文
和一般函数的区别
  • 箭头函数是没有原型的prototype
  • this指向不同
  • 箭头函数没有自己的arguments

模板字符串

var str = 'abc'
var strHtml = `<p>${str}</p>`

var、let、const之间的区别

  • var声明变量可以重复,但是let不行
  • var不限与块级
  • var定义的变量会在window上挂在
  • const声明之后必须赋值,否则会报错
  • const定义不可变,改变了也会报错

Set

Set可以用来做数组去重

class/module

class类

module模块

es5和es6的区别?说一下你知道的es6中的新增内容,es7、es8、es9等新增的有哪些

https://juejin.im/post/5b9cb3336fb9a05d290ee47e

模块化开发

前端工程化,就是用做工程的思维看待和开发自己的项目

模块化开发,就是把一个项目拆分成细小的模块,进行单独的开发,开发之后把模块进行拼装,组成一个完整的项目

组件化,是项目中一些可以复用的代码或者页面拆分成组件

好处

  • 便于分工协作,多人开发互不影响
  • 提高代码的复用率
  • 可维护性更强

模块化开发遵循原则:高内聚低耦合,每一个模块都具有完整的功能,和其他模块直接尽量避免不必要的调用操作。每一个某块都能独立完成一个功能

前端模块化方案

  • CommonJS

    是node中的模块加载规范。每个文件就是一个模块,有自己的作用域。在使用的时候使用require进行引入。在服务器端,模块的加载是运行时同步加载的;在浏览器端,模块需要提前进行编译打包

    特点

    • 所有代码都运行在单独的模块作用域内,不会污染全局变量
    • 模块可以多次加载,但是只会在第一次加载时运行一次,以后都是读取的缓存
    • 按照代码中出现的先后顺序执行加载

    使用

    module.exports = {} // 导出
    
    const m = require('xxx')  // 引入
    
  • AMD

    最早时候是require.js中使用,amd是异步加载

    定义模块的时候使用define关键字进行

    define(function() {
        return ...
    }) // 定义一个模块
    
    // 引入
    require(['m1', 'm2'], function(m1, m2) {
        
    })
    
  • CMD

    是Sea.js提出的一个加载方案,主要- 用在浏览器中,模块加载是异步的,在使用的时候会被加载执行。

  • ES6中的模块化

ES6中的模块化语法,使用export进行导出,使用import进行引入

// xx.js
const a = 9
const sum = (a, b) => a + b

export { a, sum }

// 使用
import {a, sum} from './xx'
function demo() {
    sum(2, 3)
}
总结

灵魂性的问题

你是怎么理解前端开发这个岗位的?

  • 理解前端要做的事情是什么

    一定要明白前端要做的事情是把ui设计师做的图片转换成页面,完整的展示给用户,前端就是切图的

    要保证我们做的页面是完整的,用户体验要好,交互性要完整

  • 理解前端面向的群体(客户体)是什么

    前端开发需要面向客户,最终客户能看到的是前端做的东西,所以一定要保证用户体验好

    前端还需要和ui沟通好,一定不要让ui设计师出一些奇葩的想法

    前端还要和产品经理沟通好,保证页面交互的完整性、流畅性,系统要功能合理并且完整

    前端还要面对服务器端开发人员,要对他们提供的数据接口提出要求

  • 掌握的技能有哪些

    • 沟通能力
    • 模仿能力,要经常收集一些好的效果
    • 百度解决问题的能力
    • div+css基本技能
    • 前端常见框架的使用vue,react,各种小程序
    • css动画和绘图的使用,animate.css、canvas、echarts等
    • app开发,flutter和混合开发(可选技能)

你的职业规划是什么?你当前的定位是什么?

职业规划:

​ 纯技术路线,往专家、架构师、研发经理、CTO方向走

​ 管理岗项目(产品)经理、技术负责人、部门总监

你觉得你相对来说有什么优势?

自己想一下优势

如果前端分为初中高三个级别,你属于哪个级别

会切图和前端框架(vue+react)大部分人都说自己是中高级前端开发,三年以上经验

框架用的不熟,静态页面制作还行,都说自己是初级开发,一般都一到两年经验

是否独立完成过项目

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值