前端面试题

总结自己以及其他几位面试者的部分面试题

1、MD5加密

下载插件 在计算属性中 添加

将前端的值或者内容加密 例如将password类型改成text可以看到密码

2、数组,some方法

摘自:https://blog.csdn.net/wang729506596/article/details/83019131

1.push() 后增

push()方法可以向数组后添加一个新的元素,并返回新数组的长度。

末尾添加,返回长度,改变原数组

2.unshift() 前增

unshift()可以向数组前添加一个或多个元素,并返回新的长度

首部添加,返回长度,改变原数组

3.pop() 后删

pop() 用于删除并返回最后一个元素。

尾部删除,返回被删除的元素,改变原数组

4.shift() 前删

shift() 用于删除并返回首个元素

删除首部元素,返回被删元素,改变原数组

\5. splice() 修该删除

splice(index,length,增加的元素1,增加的元素2…,增加的元素N) 表示从index开始删除length个元素,并从index开始新增元素1~N,放回被删除的元素组成的数组

对数组进行删除修改,返回被删除的元素组成的数组,改变原数组

6.concat() 拼接

concat() 方法用来合并两个或多个数组

合并两个或多个数组,返回新数组,不会改变原数组

7.slice() 剪切

slice(startIndex,endIndex) 返回从startIndex开始(包括),到endIndex(不包括)之间的原属组成的数组

返回新数组,不改变原数组

8.join()

join() 方法用来将数组转换为字符串

不改变原数组,返回转换后的字符串

9.sort() 排序

按ascii码排序

改变原数组,返回排序后的数组

10.reverse() 颠倒顺序

reverse() 方法用于颠倒数组中元素的顺序。

返回的是颠倒后的数组,会改变原数组。

11.indexOf()和lastIndexOf()

indexOf(某元素,startIndex) 从startIndex开始,查找某元素在数组中的位置,若存在,则返回第一个位置的下标,否则返回-1

lastIndexOf(某元素,startIndex) 和indexOf()相同,区别在于从尾部向首部查询

不会改变原数组,返回找到的index,否则返回-1

若不使用下标,则一般通过includes()方法代替indexOf()

12.filter() 过滤

filter() 方法返回数组中满足条件的元素组成的新数组,原数组不变

filter()的参数是一个方法

13.map() 格式化数组

map() 方法来根据需求格式化原数组,返回格式化后的数组。原数组不变

14.every()

对数组的每一项都运行给定的函数,若每一项都返回 ture,则返回 true

15.some()

对数组的每一项都运行给定的函数,若存在一项或多项返回 ture,则返回 true

16.forEach() 数组遍历

遍历整个数组,中途不能中断

3、插槽(作用)

作用:插槽可以对已有组件的结构进行自定义

  • 默认插槽:

    ​在组件标签中间可以传递一些子节点

    ​组件内部利用slot标签进行接收

  • 具名插槽

    在组件标签中间通过定义slot的名字传递子节点

<my-banner>
  <div slot="header">
    头部
  </div>
  <div slot="footer">
    底部
  </div>
</my-banner>

​ 组件内部利用slot的name进行对应接收

<template id="banner">
  <div>
    <slot name="header"></slot>
    <slot name="footer"></slot>
  </div>
</template>
  • 作用域插槽

    在组件内部定义数据,将数据传递给插槽的结构

    通过给slot动态绑定属性

    <template id="my-li">
        <ul>
          <li v-for="item in arr">
            <slot :row="item"></slot>
          </li>
        </ul>
      </template>
    

    插槽内部:通过slot-scope=“scope”来接收

    <my-li>
      <template slot-scope="scope">
        <p>{{scope.row}}</p>
      </template>
    </my-li>
    <my-li>
      <template slot-scope="scope">
        <a href="04-侦听器.html">{{scope.row}}</a>        
      </template>
    </my-li>
    

4、jquery创建数组

1.
//创建一个测试数组
var array = new Array();
boxIds.push(12182);
boxIds.push(12183);
boxIds.push(12184);
2.
var arr = new Array();
 
arr[0] = 1;
arr[1] = "a";
arr[2] = '无线';
3.
var a = new Array(1, 2, 3, 4, 5);
var b = [1, 2, 3, 4, 5];
4.多维数组

(1).
var a = new Array();
a[0] = new Array();
a[0][0] = 1;
(2).
var a = new Array([1,2,3], [4,5,6],  [7,8,9]);
var b = [[1,2,3], [4,5,6], [7,8,9]];

5、生命周期

​ 生命周期:是指一个对象从创建到运行到销毁的整个过程,被称为生命周期

生命周函数:在不同的生命周期阶段会自动执行对应的函数,而这些函数则被成为生命周期函数

// 创建阶段
      beforeCreate() {
        // 这个生命周函数,代表开始创建实例了
        console.log('beforeCreate',this.num)
      },
      created () {
        // 代表数据和方法已经初始化成功了,此处dom还没有挂载到页面上
        console.log('created',this.num,this.$el)
      },
      beforeMount () {
        // 挂在之前
        console.log('beforeMount',this.$el)
      },
      mounted () {
        // dom已经挂载了
        console.log('mounted',this.$el)
      },
      // 运行更新阶段
      beforeUpdate () {
        // 数据更新,页面还没有同步
        console.log('beforeUpdated',this.num,document.getElementById('app').innerHTML)
      },
      updated () {
        // 数据更新,页面已经同步
        console.log('updated',this.num,document.getElementById('app').innerHTML)
      },
      // 销毁阶段
      beforeDestroy () {
        // 销毁之前
        console.log('beforeDestroy')
      },
      destroyed () {
        // 已经销毁了
        console.log('destroy')
      }

6、回调函数场景

​ 异步的时候,回调拿到异步的结构

7、CMD、AMD

  • 按下enter键会执行的流程
  • 首先会根据这个域名发送请求 将域名传送到服务器 跟服务器上的ip地址匹配 返回数据给客户端

​ AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。

​ CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。

区别:

  1. 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行
  2. CMD 推崇依赖就近,AMD 推崇依赖前置
  3. AMD 的 API 默认是一个当多个用,CMD 的 API 严格区分,推崇职责单一

8、在created中操作DOM

这个函数是可以等dom重新更新完成会调用

数据渲染完成,页面完成更新即调用this.$nextTik

当修改了数据,dom是异步同步的,所以,如果更改了数据,在修改数据下面重新操作dom会出问题,需要保证dom也更新完成才能操作

9、watch和computed的区别

​ computed是计算属性,依赖其它属性值,并且computed的值有缓存,只有它依赖的属性值发生改变,
下一次获取computed的值才会重新计算computed的值
watch更多的是[观察]的作用,类似某些数据的监听回调,每当监听的数据变化时都会执行回调进行后续操作
当我们需要数值计算,并且依赖其它数据时,应该使用computed,因为可以利用computed的缓存特性,避免每次获取值,都要重新计算;
当我们需要在数据变化时执行异步或开销较大的操作时,应该使用watch,使用watch选项允许我们执行异步操作,限制我们执行操作大的频率,
并且在我们得到最终结果前,设置中间状态,这些都是计算属性无法做到的。

10、常见web安全及防护原理

​ xss、sql注入原理

sql注入原理
具体就是通过把sql命令插入到web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意sql命令

xss
跨站脚本(Cross-site Scripting)是一种网站应用程序的安全漏洞攻击,是代码注入的一种。它允许恶意用户将代码注入到网页上,其他用户在观看网页时就会受到影响。这类攻击通常包含了HTML以及用户端脚本语言。

11、哪些操作会造成内存泄露

js造成内存泄漏的几种情况:
全局变量 闭包引起的内存泄露 没有清理的DOM元素引用 被遗忘的定时器或者回调 子元素存在引起的内存泄露

12、null和undefined的区别

​ null作为函数的参数,表示该函数的参数不是对象,作为对象原型链的终点,null表示”没有对象”,即该处不应该有值。典型用法是

​ null表示空 undefined定义后未赋值

13、Js怎么实现继承

摘自:https://www.cnblogs.com/humin/p/4556820.html

首先创建一个父类:

1、原型链继承 核心: 将父类的实例作为子类的原型

2、构造继承 **核心:**使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)

3、实例继承 **核心:**为父类实例添加新特性,作为子类实例返回

5、组合继承 **核心:**通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用

6、寄生组合继承 **核心:**通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点

4、拷贝继承

function Cat(name){
  var animal = new Animal();
  for(var p in animal){
    Cat.prototype[p] = animal[p];
  }
  Cat.prototype.name = name || 'Tom';
}

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true

14、实现一个Js数组的去重

摘自:https://www.jb51.net/article/118657.htm

1、双层循环,外层循环元素,内层循环时比较值

如果有相同的值则跳过,不相同则push进数组

2、利用splice直接在原数组进行操作

双层循环,外层循环元素,内层循环时比较值

值相同时,则删去这个值

注意点:删除元素之后,需要将数组的长度也减1.

3、利用对象的属性不能相同的特点进行去重

4、数组递归去重

运用递归的思想

先排序,然后从最后开始比较,遇到相同,则删除

5、利用indexOf以及forEach

6、利用ES6的set

Set数据结构,它类似于数组,其成员的值都是唯一的。

利用Array.from将Set结构转换成数组

function dedupe(array){
 return Array.from(new Set(array));
}
dedupe([1,1,2,3]) //[1,2,3]
// 拓展运算符(...)内部使用for...of循环
let arr = [1,2,3,3];
let resultarr = [...new Set(arr)]; 
console.log(resultarr); //[1,2,3]

7、concat()方法

思路:concat() 方法将传入的数组或非数组值与原数组合并,组成一个新的数组并返回。该方法会产生一个新的数组。

function concatArr(arr1, arr2){
  var arr = arr1.concat(arr2);
  arr = unique1(arr);//再引用上面的任意一个去重方法
  return arr;
}

15、vue生命周期的理解

同上

16、 r o u t e 、 route、 routerouter的区别

route是当前路由信息,可以获取到当前路由地址参数等等
router是全局路由(VueRouter)实例对象,可以通过router进行路由的跳转后退等等

$route为当前router跳转对象里面可以获取name、path、query的值;

$router为Vue-router实例;

想要导航到不同URL,则使用$router.push方法

17、Vue中怎么自定义过滤器

在组件内部通过filters来创建一个局部过滤器

全局过滤器和局部过滤器的区别

局部过滤器:只能在当前的组件中使用

全局过滤器: 在任意地方使用

18、H5标签有哪些?

​ h5标签,:内容标签article,footer,header;表单:date,time,Email;媒体video,audio,本地缓存:localstorage,sessionstorage等

19、css画一个响应式正方形(请勿直接使用vw、vh、rem)

正方形
position:absolute;
border:1px solid red;
padding: 0 20% 20% 0;

20、缓存的几种方式以及区别

​ cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存

​ cookie数据不能超过4k sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。

21、ES6数组的新方法有哪些

​ map 、reduce 、filter、some、sort、reverse(倒序)

  1. find()

找到数组中第一次满足条件的元素,并返回,若找不到则返回undefined。不改变原数组。

和filter()方法的区别在于:filter返回值是所有满足条件的元素组成的数组,

一般在需要使用找到的元素时,用find()方法

2.findIndex()方法

findIndex()的作用同indexOf(),返回第一个满足条件的下标,并停止寻找。

区别是findIndex() 的参数为一个回调函数,且一般用于对象数组

3.includes()

includes()方法,返回一个布尔值。 参数是一个value,一般用于简单数组。

对于复杂数组,则可以使用some()方法替代includes()方法

4.Array.isArray()方法

用来判断一个元素是否为数组

22、实现一个js数组去重

// 数组去重
var arr = [1,2,3,4,5,4,3,2,1]
        function fn(arr) {
          let newArr = []
          for(let i = 0;i < arr.length;i++) {
              if(!newArr.includes(arr[i])) {
                  newArr.push(arr[i])
              }
          }
          return newArr
        }
        console.log(fn(arr));

23、怎么清除cdn 浏览器缓存

24、用过es6的api么,对象的,数组的,还有函数里面的

25、请写出一个函数,给定任意一个值,判断其属于JavaScript中的哪一种数据类型

function type(val) {
// ... 写出你的实现方法
return Object.prototype.toString.call(val)
}
let a = 3; // type(a) => 'Number'
let b = [2, 1]; // type(b) => 'Array'
let c = (a, b) => a+b; // type(c) => 'Function'
let d = { a, b } // type(d) => 'Object'
let e = null // type(d) => 'Null'
let f = /\.png$/ // type(f) => 'RegExp'
let g = Symbol('fool') // type(g) => 'Symbol'

Object.prototype.toString.call(null); // "[object Null]"
Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call('abc');// "[object String]"
Object.prototype.toString.call(123);// "[object Number]"
Object.prototype.toString.call(true);// "[object Boolean]"
console.log(type(a))
console.log(type(b))
console.log(type(c))
console.log(type(d))
console.log(type(e))
console.log(type(f))
console.log(type(g))

26、怎么清除cdn缓存

  • 只要重新同步一次最新的,之前缓存就都没了

  • 1.打开命令对话框:开始–cmd–确定

    2.在CMD命令操作框上输入清空DNS缓存的命令,命令为:ipconfig/flushdns ,然后回车即可清除DNS缓存。

27、怎么清除cookie

浏览器–设置–清除cookie

28、ES6 解构

29、webpack

  • 1> 连接: webpack从入口JS开始, 递归查找出所有相关联的模块, 并连接起来形成一个图(网)的结构
  • 2> 编译: 将JS模块中的模块化语法编译为浏览器可以直接运行的模块语法(当然其它类型资源也会处理)
  • 3> 合并: 将图中所有编译过的模块合并成一个或少量几个bundle文件, 而浏览器运行是打包生成的bundle文件
  • 说说你对项目构建的理解
    1). 构建项目到底做些什么 编译项目中的js, sass, less, stylus 合并js/css等资源文件 压缩js/css/html等资源文件 JS语法的检查 2). 构建工具 作用: 简化项目构建, 实现自动化构建 常用: grunt/gulp/webpack
  • 区别webpack与gulp/grunt
    1). webpack是一种模块化打包工具,主要用于模块化方案,预编译模块的方案。
    2). Grunt/Gulp是非模块化打包工具, 是工具链,可以配合各种插件做js压缩,css压缩,less编译 替代手工实现自动化工作

30、将下列数组相同name属性的num,并倒序排列

 let list = [
      { name: 'a', num: 1},
      { name: 'a', num: 1},
      { name: 'b', num: 2},
      { name: 'b', num: 2},
      { name: 'c', num: 3},
      { name: 'c', num: 3},
      { name: 'd', num: 9},
    ]

    const newList = []
    list.forEach(item => {
      const index = newList.findIndex(newItem => newItem.name === item.name )
      // 如果没有符合条件的元素返回 -1
      if (index !== -1) {
        newList[index].num += item.num
      } else {
        newList.push(item)
      }
    })
	//  sort() 方法用于对数组的元素进行排序
    console.log(newList.sort((a,b) => {
      return b.num - a.num
    }))

31、将多维数组转化为一维数组

 <script>
    var arr = [1,2,3,[4,5,6,[7,8,9,[10,11]]],[111,222]]

    // join方法
    // const newArr = arr.join(',')

    // toString方法
    // const newArr = arr.toString().split(',').map(item => item - 0)
    // flat方法
    // const newArr = arr.flat(Infinity)

    // 递归方法
    const newArr = []
    function deep(arr2) {
      arr2.forEach(item => {
        if (typeof item === 'object') {
          deep(item)
        } else {
          newArr.push(item)
        }
      })
    }
    deep(arr)
  </script>

32、问题: 项目中获取数据失败404,代码无误||或者,面试官:你开发的项目中有没有遇到比较难解决的问题,你在写项目的时候,功能有什么亮点?

有的,当时在开发项目的时候,遇到了一个这样的问题,就是后台返回的数据的id,和我拿到的id不一样,这个问题困扰了好久,最后发现数值大于2的53次方之后,数值就不精确了,后台返回的数据超过了2的53次方。终于找到了bug的具体问题。后来又发现后台返回数据的时候axios帮我处理了这个数据,最终处理的有问题,所以,我就不打算让axios处理响应的数据了,所以就需要获取到后台返回的源数据,axios.create内部的transformResponse就可以获取到源数据,又遇到新的问题,如何自己处理后台返回的的数据包含大数的问题,最终在网上找了好久,终于找到了一个插件json-bigint这个插件,利用这个插件的parse方法即可处理大数,但是 json-bigint在处理大数的时候将大数处理成了一个对象,还需要将这个处理之后的对象转成字符串才可以使用

后台返回的是字符串, axios 转为json数据,数值超过2的53次方,就不精确了,易出错 (是axios转换导致的错误404)

​ 原因:文章、id不对、(id过长)

​ 从network中找到后台返回数据 id,与vue调试工具中的 id 对比 发现id值不一样

解决:利用json-bigint处理大数字问题

json-bigint 是一个第三方包,它可以帮我们很好的处理这个问题。

json-bigint 会把超出 JS 安全整数范围的数字转为一个 BigNumber 类型的对象,对象数据是它内部的一个算法处理之后的,我们要做的就是在使用的时候转为字符串来使用。

通过 Axios 请求得到的数据都是 Axios 处理(JSON.parse)之后的,我们应该在 Axios 执行处理之前手动使用 json-bigint 来解析处理。Axios 提供了自定义处理原始后端返回数据的 API:transformResponse

34、项目优化:

1.项目优化- -进度条添加搜索npr ogr ess进行安装即可

2.移除打包之后的console

npm install babel-plugin-tr ans for m-r emove-console --save-dev打开babel. config.js文件在

plugins节点下新增"tr ans form-r emove-console"

3.只在发布阶段移除console

利用pr ocess . env. NODE_ ENV判断当前是发布是开发阶段

利用展开运算符将数组里面的插件交给plugins

4.双击打开页面

创建> vue . config. js文件

js内部暴露出- -个配置对象

publicPath: './'将根路径修改为相对路径

5.根据不同的环境配置不同的入口文件

6.通过cdn加载外部资源

7.配置element -ui的cdn资源

8.根据不同环境定制不同的首页内容

9.实现路由懒加载

npm insta1ll --save-dev @babel/p1ugin-syntax- dynamic- import配置babe1-plugins

//引入路由懒加载

“@babe1/p lugin-synt ax-dynami c- import”

修改引入方式,相同的组webpackChunkName相同

35、浏览器兼容问题

1、Vue的话借助postCsschain解决兼容

2、html5Shiv解决h5标签兼容

3、response.js解决媒体查询兼容

36、cookie与session区别

摘自:https://www.cnblogs.com/pengc/p/8714475.html

cookie和session都是用来跟踪浏览器用户身份的会话方式。

1、保持状态:cookie保存在浏览器端,session保存在服务器端

2、使用方式:(1)cookie机制:如果不在浏览器中设置过期时间,cookie被保存在内存中,生命周期随浏览器的关闭而结束,这种cookie简称会话cookie。如果在浏览器中设置了cookie的过期时间,cookie被保存在硬盘中,关闭浏览器后,cookie数据仍然存在,直到过期时间结束才消失。

​ Cookie是服务器发给客户端的特殊信息,cookie是以文本的方式保存在客户端,每次请求时都带上它

(2)session机制:当服务器收到请求需要创建session对象时,首先会检查客户端请求中是否包含sessionid。如果有sessionid,服务器将根据该id返回对应session对象。如果客户端请求中没有sessionid,服务器会创建新的session对象,并把sessionid在本次响应中返回给客户端。通常使用cookie方式存储sessionid到客户端,在交互中浏览器按照规则将sessionid发送给服务器。如果用户禁用cookie,则要使用URL重写,可以通过response.encodeURL(url) 进行实现;API对encodeURL的结束为,当浏览器支持Cookie时,url不做任何处理;当浏览器不支持Cookie的时候,将会重写URL将SessionID拼接到访问地址后。

3、存储内容:cookie只能保存字符串类型,以文本的方式;session通过类似与Hashtable的数据结构来保存,能支持任何类型的对象(session中可含有多个对象)

4、存储的大小:cookie:单个cookie保存的数据不能超过4kb;session大小没有限制。

5、安全性:cookie:针对cookie所存在的攻击:Cookie欺骗,Cookie截获;session的安全性大于cookie。

原因如下:(1)sessionID存储在cookie中,若要攻破session首先要攻破cookie;

2)sessionID是要有人登录,或者启动session_start才会有,所以攻破cookie也不一定能得到sessionID;

(3)第二次启动session_start后,前一次的sessionID就是失效了,session过期后,sessionID也随之失效。

(4)sessionID是加密的

5)综上所述,攻击者必须在短时间内攻破加密的se

37、路由组件传参的所有方式

分别为:布尔模式、对象模式、函数模式

组件中:通过this. r o u t e r . p u s h 进 行 编 程 式 路 由 跳 转 、 r o u t e r − l i n k 中 的 t o 属 性 进 行 路 由 切 换 。 通 过 t h i s . router.push进行编程式路由跳转、router-link中的to属性进行路由切换。通过this. router.pushrouterlinktothis.route.params/this.$route.query获取路由传递的参数**。

总结
1.this, r o u t e r . p u s h 进 行 编 程 式 路 由 跳 转 2. r o u t e r − l i n k 进 行 页 面 按 钮 式 路 由 跳 转 3. t h i s . router.push进行编程式路由跳转 2.router-link进行页面按钮式路由跳转 3.this. router.push2.routerlink3.this.route.params获取路由传递参数
4.this.$route.query获取路由传递参数
5.params和query都是传递参数区别在于params不会再url上显示出现,
并且params参数是路由的一部分,是一定要存在的,否则无法显示视图。
query则是我们通常看到的url后面跟上的?后跟的显示参数

###39、js数组方法,哪个方法会改变原函数,es6新增特性

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值