初级高频面试题

常用手写代码

var 和 let const 的区别

var是ES5语法,let const是ES6语法;var有变量提升
var和let是变量,可修改;const是常量,不可修改
let const 有块级作用域,var没有

typeof 能判断哪些类型

能够判断所有值类型 已及 函数和对象类型
undefined string number boolean symbol
object (注意,typeof null === 'object')
function

列举强制类型转换和隐式类型转换

强制:parseInt parseFloat toString等
隐式:if、逻辑运算、==、+拼接字符串

split()和 join()的区别
"1-2-3"
  .split("-") // [1,2,3]
  [(1, 2, 3)].join("-"); // '1-2-3'
数组的 pop push unshift shift 分别做什么
// pop 移除最后一个元素,并返移除元素
const arr = [1, 2, 3, 4, 5];
const resResult = arr.pop();
console.log(resResult, arr);

// push 最后添加一个元素,并返回数组长度
const arr = [1, 2, 3, 4, 5];
const resResult = arr.push();
console.log(resResult, arr);

// unshift 最前面添加一个元素,并返回数组长度
const arr = [1, 2, 3, 4, 5];
const resResult = arr.unshift(6);
console.log(resResult, arr);

// shift 移除第一个元素,并返回移除元素
const arr = [1, 2, 3, 4, 5];
const resResult = arr.shift();
console.log(resResult, arr);

// 纯函数:1,不改变源数组(没有副作用);2,返回一个数组
数组 slice 和 splice 的区别
const arr = [10, 20, 30, 40, 50];
// slice纯函数 截取
const arr1 = arr.slice();
const arr2 = arr.slice(1, 4);
const arr3 = arr.slice(2);
const arr4 = arr.slice(-3);

// splice 非纯函数 剪接的用途
const spliceRes = arr.splice(1, 2, "a", "b", "c");
console.Log(spliceRes, arr);
[10,20,30].map(parseInt)返回结果是什么
const res = [10, 20, 30].map(parseInt);
console.log(res) // [10, NaN, NaN]

  [
    // 拆解
    (10, 20, 30)
  ].map((num, index) => {
    return parseInt(num, index);
  });
ajax 请求 get 和 post 的区别

get 一般用于查询操作,post 一般用户提交操作
get参数拼接在url 上 , post放在请求体内(数据体积可更大)
安全性: post易于防止 CSRF

函数 bind 和 call 及 apply 的区别

bind返回改变了上下文后的一个函数。

fn.bind(this)

call和apply改变了函数的this上下文后便执行该函数。

call()方法的作用和 apply() 方法类似, 区别就是call()方法接受的是参数列表,而apply()方法接受的是一个参数数组

fn.call(this, p1, p2, p3);
fn.apply(this, arguments);
事件代理(委托)是什么
const p1 = document.getElementById("p1");
const body = document.body;
bindEvent(p1, "click", (e) => {
  e.stopPropagation(); // 注释掉这一行,来体会事件冒泡
  alert("激活");
});
bindEvent(body, "click", (e) => {
  alert("取消");
});
闭包是什么?有何特性 有何影响

闭包: 函数 作为参数被传入,作为返回值被返回
回顾作用域和闭包

影响︰变量会常驻内存,得不到释放。闭包不要乱用

阻止事件冒泡和默认行为

阻止事件冒泡event.stopPropagation()

阻止默认行为event.preventDefault()

如何减少 DOM 操作

缓存DOM查询结果

多次DOM操作,利用文档片段DocumentFragment,合并到一次插入

解释 jsonp 原理,为何不是真正的 ajax

示例,说明参考

<script>
  window.abc = function (data) {
    console.log(data);
  };
</script>
<script src="http://localhost:8002/jsonp.js?username=xxx&callback=abc"></script>
// jsonp.js
adb({ name: "xxx" });
==和===的区别

== 会尝试类型转换
=== 严格相等

函数声明和函数表达式的区别
// const res = sum( 10,20)
// lconsole.log(res)

//函数声明
// function sum(x, y){
// return x+y
// }

var res = sum(10, 20);
console.log(res);

// 函数表达式
var sum = function (x, y) {
  return x + y;
};
new Object()和 Object.create()的区别

{} 等同于 new Object() ,原型Object.prototype
Object.create(null)没有原型
Object.create({...})可指定原型

关于 this 的场景题
const User = {
  count: 1,
  getCount: function () {
    return this.count;
  },
};
console.log(User.getCount()); // 1
const func = User.getCount;
console.log(func()); // undefined
判断字符串以字母开头,后面字母数字下划线,长度 6-30

const reg = /^[a-zA-Z]w{5,29}$/;

如何获取多个数字中的最大值
function max() {
  const nums = Array.prototype.slice.call(arguments); // 变为数组
  let max = 0;
  nums.forEach((n) => {
    if (n > max) {
      max = n;
    }
  });
  return max;
}
如何用 JS 实现继承

class继承 ES6
prototype继承 ES5

如何捕获 JS 程序中的异常
try {
  // todo
} catch (ex) {
  console.error(ex); //手动捕获catch
} finally {
  // todo
}

//自动捕获
window.onerror = function (message, source, lineNam, colNom, error) {
  //第一,对跨域的js ,如CDN 的,不会有详细的报错信息
  //第二,对于压缩的 js ,还要配合sourceMap反查到未压缩代码的行、列
};
什么是 JSON

json是一种数据格式,本质是一段字符串。
json格式和JS对象结构一致,对JS语言更友好
window.JSON是一个全局对象:JSON.strinqify JSON.parse

获取当前页面 url 参数
// 传统方式,查找location.search
function query(name) {
  const search = location.search.substr(1); //类似 array.slice()
  // search: 'a=10&b=20&c=30'
  const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`, "i");
  const res = search.match(reg);
  if (res === null) {
    return null;
  }
  return res[2];
}
query(a);

// 新 API ,URLSearchParams

function query(ngme) {
  const search = location.search;
  const p = new URLSearchParams(search);
  return p.get(name);
}
console.log(query("b"));
将 url 参数解析为 JS 对象
//传统方式,分析search
function queryToObj() {
  const res = {};
  const search = location.search.substr(1); //去掉前面的?
  search.split("&").forEach((paramStr) => {
    const arr = paramStr.split("=");
    const key = arr[0];
    const val = arr[1];
    res[key] = val;
  });
  return res;
}

// 使用 URLSearchParams
function queryToObj() {
  const res = {};
  const pList = new URLSearchParams(location.search);
  pList.forEach((val, key) => {
    res[key] = val;
  });
  return res;
}
数组去重
// 传统方式,遍历元素挨个比较、去重
// 使用Set
// 考虑计算效率

// 传统方式
function unique(arr) {
  const res = [];
  arr.forEach((item) => {
    if (res.indexOf(item)) {
      res.push(item);
    }
  });
  return res;
}

// Set (无序,不能重复)
function unique(arr) {
  const set = new Set(arr);
  return [...set];
}

const res = unique([30, 10, 20, 30, 40, 10]);
console.log(res);
介绍一下 RAF requestAnimationFrame
// 要想动画流畅,更新频率要60帧/s ,即16.67ms 更新一次视图
// setTimeout 要手动控制频率,而 RAF浏览器会自动控制
// 后台标签或隐藏iframe中,RAF 会暂停,而setTimeout依然执行

let curWidth = 100;
const maxWidth = 640;

// setTimeout
function animate() {
  curWidth = curWidth + 3;
  $div1.css("width", curWidth);
  if (curWidth < maxWidth) {
    setTimeout(animate, 16.7); //自己控制时间
  }
}
animate();

// RAF
function animate() {
  curwidth = curwidth + 3;
  $div1.css("width", curwidth);
  if (curwidth < maxwidth) {
    window.requestAnimationFrame(animate); // 时间不用自己控制
  }
}
animate();
前端性能如何优化 一般从哪几个方面考虑

原则: 多使用内存、缓存,减少计算、减少网路请求
方向︰ 加载页面,页面渲染,页面操作流畅度

window.onload 和 DOMContentLoaded 的区别
window.addEventListener("load ", function () {
  //页面的全部资源加载完才会执行,包括图片、视频等
});
document.addEventListener("DOMContentLoaded ", function () {
  // DOM渲染完即可执行,此时图片、视频还可能没有加载完
});
axios 和 fetch 的区别
  • axios 和 fetch 都是基于 Promise 实现,支持 async await
  • axios 底层是 XMLHttpRequest,支持 IE6
  • Fetch 脱离了 XHR,兼容性不好,需要封装

1、处理10000万条数据该怎么办

放到webwork线程

2、浏览器一帧发生了什么 3、webpack SplitChunk怎么配置使用

配置cachegroups属性,这是个对象,键就是要分包出来的chunk,根据正则匹配路径,其中还有配置模块的大小限制,重复使用次数的限制,具体去webpack官网看

4、webpack 长效缓存 5、超大文件上传怎么处理

超大文件上传就要分片,把file对象分解成多个blob,一段一段的上传

6、浏览器缓存相关理解 7、浏览器的渲染机制 8、Promise.then什么时候执行

then创建了微任务,在本次执行队列执行完同步代码之后再执行里面的回调函数

9、事件循环 10、map和wekMap的区别 11、Symbol的理解 12、ES6和ES5继承的区别 13、http2新特性 14、react和vue diff算法解析与对比

总计

I/O: 多路复用 postMessage: window.postMessage()  方法可以安全地实现跨源通信。 MessageChanel: Channel Messaging API 的 MessageChannel  接口允许我们创建一个新的消息通道,并通过它的两个 MessagePort  属性发送数据。

4、v8 引擎的了解程度

5、this 指向问题

  • 箭头函数体内的 this 对象,就是定义时所在的对象,而不是使用时所在的对象。

  • 作为对象属性方法调用,都指向前面调用函数都那个对象

  • 当普通的函数,直接调用的时候,一般来说分两种情况:

  • 严格模式绑定到  undefined

  • 非严格模式绑定到全局对象  window

  • 在全局环境中无论是否是严格模式,this  均指向全局对象,例如浏览器端的  window

  • 构造函数作为指向的是你 new 出来的那个对象实例本身:

6、数据类型 BigInt 是什么作用;在不用 BigInt 的情况下,计算两个超级大的数的和,怎样保持精度不丢失

计算两个超级大的数和,可以保持精度 typeof(10n)——bignit 将数字转换成字符串,相加处理

7、嵌套多级作用域插槽如何进行参数传递

  • provide/inject

8、从架构方面说一下 Echarts 的优点

  • 丰富的可视化类型
  • 多种数据格式无需转换直接使用
  • 千万数据的前端展现
  • 移动端优化
  • 多渲染方案,跨平台使用!
  • 深度的交互式数据探索
  • 动态数据
  • 无障碍访问(4.0+)
  • 绚丽的特效
  • 通过 GL 实现更多更强大绚丽的三维可视化

9、页面生成的过程

  • HTML 转化成 DOM 树
  • CSS 转化成 CSSDOM 树
  • 结合 DOM 和 CSSDOM,生成一颗渲染树
  • 生成布局,即将所有渲染树的所有节点进行平面合成
  • 将布局绘制在屏幕上

问题摘要-珍岛集团 Ï

1、diff 算法和虚拟 DOM

diff 算法特点:

  • 1、同级比较,不会跨级别比较时间复杂度为 O(n)
  • 2、在 diff 比较的过程中,循环从两边向中间靠拢
第一步: vue 的虚拟 DOM 首先会对新老 VNode 的开始位置和结束位置进行标记
第二步: 对新老节点的比较并对应移动 VNode 节点
  • 情形一: 当新老 VNode 节点的 start 等于 sameVNode 时,直接使用 patchVnode 即可,同时新老 VNode 节点对的索引都加 1
  • 情形二: 当新老 VNode 节点的 end 等于 sameVNode 时,同样直接使用 patchNode 即可,同时新老 VNode 节点的索引值都减 1
  • 情形三: 当老 VNode 节点的 start 和新 VNode 的 end 满足 sameVnode 时候,数据更新后,oldStartVNode 跑到 oldEndVNode 后面去了,patchVnode 还要将当前真实 dom 节点移动到 oldEndVNode 后面,老 Vnode 节点索引加 1,新 Vnode 节点索引减 1
  • 情形四: 当老 VNode 的 end 节点和新 VNode 节点的 start 满足 sameVNode 时,说明数据更新后 oldEndVnode 跑到 oldStartVnode 后面去了,patchVNode 后还要将当前真实 dom 移动到 oldStartVnode 后面,老 Vnode 节点索引减 1,新 Vnode 节点所以加 1

如果都不满足以上四种情形,那说明没有相同的节点可以复用。

第三步

当 while 循环结束后,根据新老节点的数目不同,分别进行相应的节点添加和删除.如果新节点的数目大于老节点,则需要把多出来的节点创建出来添加到真实 dom 中,如果老节点数目大于新节点数目,则需要把多出来的老节点从真实 dom 中删除

2、导航路由钩子

1、全局路由钩子: beforeEach、afterEach、beforeResolve

2、单个路由钩子: beforeEnter

3、组件路由钩子: beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave

3、filter、watch 和 computed 的区别

watch:监听值,只能是 data 里面的属性,可以使用异步函数 computed:定义一个函数,这个函数会返回一个值,然后返回处理的数据,可以包含大量逻辑计算,不支持异步函数 filter:过滤器 全局过滤器: vue.filter('toFixed', (模型变量, 其他参数)) 局部过滤器: vm 控制器里面

4、指令及使用指令的钩子

全局指令

// 全局指令

Vue.directive('focus', {
  inserted: function(el) {
    el.focus()
  }
})
// 局部指令
directive: {
  focus: {
    inserted: function(el) {
      el.focus()
    }
  }
}

// 使用指令的钩子函数
bind 只调用一次,第一次绑定元素时使用
inserted 插入节点时使用
update 节点更新时使用
componentUpdated 指令所在的节点和其子节点更新时使用
unbind 只调用一次,指令与组件解绑时使用

5、上传组件包的方法

npm login 登录
npm publish 发布

6、nginx 有哪些配置

 http {
    include mime.types
    default_type application/octet-stream

    server {
        listen 80;
        server_name: localhost;

        location {
          root html;
          index index.html;
        }

        error_page 502 503 504 /50x.html;

        location = /50x.html {
          root html
        }
    }
 }

7、@async @await 与 @Promise 的关联

  • Promise 对象是一个代理对象 被代理的值在 Promise 对象创建时可能是未知的
  • async await 是 promise 的语法糖,只是为了书写代码时更流畅,增强代码可读性,定义了一个异步函数
  • await 必须出现在 async 函数内部 不能单独使用
  • await 返回的是一个 promise 对象
  • async await Reject 捕捉是用 try {} catch {}

8、@GET @POST 的区别

  • GET 请求有长度限制,而 POST 请求没有
  • GET 浏览器退回无害,POST 则会重新发起请求
  • GET 请求参数通过 URL 传递,POST 放在请求体中
  • GET 请求更不安全,因为参数暴露在 URL 上面
  • GET 产生一个 TCP 数据包 POST 产生 2 个 TCP 数据包
  • GET 请求 浏览器会把 http hdeader 和 data 一并发送出去,服务器响应 200, POST 请求 浏览器先发送 header,服务器响应 100 continue 浏览器在发送 data 服务器响应 200

9、nextTick 的原理

在下次循环 DOM 更新后执行延迟回调,在修改数据后立即执行这个方法,获取更新后的 DOM

callbacks; // 异步操作队列
pending; // 标识同一个时间只能执行一次
timerFunc; // 执行异步延迟函数

// 把回调函数放入 callbacks中等待执行
// 将执行函数放到宏任务或者微任务中
// 事件循环到了宏任务或者微任务,执行函数依次执行callbacks中的函数

10、https 缓存策略

  • 强制缓存(cache-control) 放在请求头中 max-age no-cache (不用本地缓存) no-store (不用本地和服务器缓存)

  • 协商缓存 (对比缓存) 依据服务端和客户端的资源标识符是否一样 Last Modified Etag

11、事件循环

12、ProxyTable 原理

浏览器禁止跨域,但是服务器可以.npm run dev 运行了一个服务器,ProxyTable 实际上是将请求发送给自身服务器,然后在由服务器转发给后台服务器,做了一层呆了,所以不会出现跨域问题

13、webpack 热重载

webpack 的 Watch Mode 观察模式 自动编译 需要手动刷新浏览器

webpack-dev-server web 服务器相当于启用了一个 express+http 服务器+webpack-dev-middleware 自动编译+实时重新加载浏览器

webpack-dev-middleware

14、scoped 原理

vue 通过在 DOM 结构及 css 样式上添加唯一的标记,保证唯一,达到样式私有化,不会污染全局,主要是通过 Postcss 进行转换,Postcss 给左右 dom 元素添加了一个独一无二的动态属性,组件内部 dom

15、常用的 es6 语法

Object.assign() Object.entries() Object.keys() Object.values()

Array.from() Array.of()

Symbol

Set() Map()

16、输入一个 url 请求到页面展示经历了哪些过程

1、DNS 解析 2、TCP 连接 3、发送 HTTP 请求 4、服务器处理请求并返回 HTTP 报文 5、浏览器解析并渲染页面 6、连接结束

17、for 和 forEach 的区别

for 循环可以中断循环 forEach 不可以中断

for 循环是一种循环机制,只是能通过它遍历数组

forEach 是负责遍历可迭代对象

性能比较 for > forEach

18 防抖和节流

节流: n 秒后只运行一次,n 秒内重复触发,只有一次生效 防抖: n 秒后执行该事件,n 秒内重复触发,则重新计时

问题摘要-米哈游

1、处理 10000 万条数据该怎么办 2、浏览器一帧发生了什么 3、webpack SplitChunk 怎么配置使用 4、webpack 长效缓存 5、超大文件上传怎么处理 6、浏览器缓存相关理解 7、浏览器的渲染机制 8、Promise.then 什么时候执行 9、事件循环 10、map 和 wekMap 的区别 11、Symbol 的理解 12、ES6 和 ES5 继承的区别 13、http2 新特性

最后更新时间:
贡献者: DESKTOP-ER5718D\zt