JS 扫盲题 ( 面试题梳理系列 (一))

1,211 阅读8分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情

写在前面

有句话说得好,当潮水退去时,才知道到底谁在裸泳,在最近这种危机四伏的情况下,唯一能做的,就是做好随时应对面试的准备,让自己在危机真正来临之时,更加从容不迫,游刃有余。在接下来这段时间,我将持续更新前端相关的各种面试高频题目,供大家一起学习、探讨,给自己备好充足的弹药,准备随时上战场。

箭头函数优缺点以及什么时候不能用?

优缺点

优点:

1、写法更加简洁
2、隐式返回,可以不写 return

function fn(name){
  console.log(`I am ${name}`)
}
// 箭头函数
const fn = (name) => console.log(`I am ${name}`)

缺点:

1、无法通过 arguments 获取参数

function fn(name,id){
  console.log(arguments)
}
// 箭头函数
const fn2 = (name,id) => console.log(arguments)
fn('yimwu', 1)  // ['yimwu', 1]
fn2('yimwu', 1) // arguments is not defined

2、无法通过 call、bind、apply 改变 this 指向,this 永远指向定义位置的 this

const fn = () => console.log(this) // Window 对象
function fn2(){
  console.log(this) // Window 对象
}
fn.call({name: 'yimwu'}) // Window 对象
fn2.call({name: 'yimwu'}) // {name: 'yimwu'}

不适用的场景

1、作为对象内置函数,不能读取对象内其他值

这个本质上是因为 箭头函数的 this 不可改变,并且永远指向定义时对应的 this 也就是 window

const obj = {
      name: 'yimwu',
      tel: '139xxxxx839',
      address: 'guangzhou',
      getInfo: () => { console.log(this, this.name, this.tel, this.address) } // name、tel、address is not defined  this 为 window
    }
    obj.getInfo()

2、不能作为构造函数

由于构造函数需要将传入的参数挂载到 this 上,最后返回 this 对象,达到构造的目的,因此又是设计到 this 的指向问题,由于构造函数 this 指向原因,因此无法完成该需求

const fn = (name, tel) => {
  this.name = name
  this.tel = tel
}

const person = new fn('yimwu', '139xxxxx839') // fn is not a constructor

3、不能在动态上下文中绑定

由于 this 需要动态获取,而箭头函数的 this 又是固定的,因此无法获取到正确的 this

const btn = document.querySelector('.btn')
btn.addEventListener('click', () => {
  this.innerText = '!! Clicked !!'
})

for await of 用法

for of / for in

先回顾一下两个容易混淆的 for 用法
for in 遍历的是 key 值,而 for of 遍历的是 value 值

const arr = [10,20,30]
for(item in arr){
  console.log(item) // 0 1 2
}
for(item of arr){
  console.log(item) // 10 20 30
}

for await of

与 for of 类似,只不过 for of 是同步的,而 for await of 是异步的,对于向 Promise 的这种异步执行的代码,需要用 for await of 代替 for of, 才能避免发生顺序错乱的结果,需要注意的是,for await 其实可以看做是 ES9 自动完成异步操作的一个语法糖,因此同样也需要在 async 修饰的函数中才能够使用

function fn(val,time){
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(val)
    }, time);
  })
}

const promiseTest = async () => {
  const p1 = fn('yimwu',5000)
  const p2 = fn('YI',6000)
  const p3 = fn('WU',1000)
  const arr = [p1,p2,p3]
  for await(let p of arr){
    console.log(p)
  }
}

promiseTest() // yimwu YI WU

说说 JS 严格模式的特点

从 JS 发展历史的角度来看,我们知道 JS 存在许多问题,有很多不严谨或者是不够安全的地方,所以当我们需要将 JS 应用到生产环境中去的时候,我们就需要使用 JS 的严格模式来限制我们的行为,达到更加安全,可控的效果

开启方式

1、在全局上开启

'use strict'

const fn = () => {
  console.log('I am Yimwu')
}

2、在函数中开启

function fn(){
  'use strict'
  console.log('I am Yimwu')
}

严格模式限制

1、全局变量必须声明

我们都知道 JS 中默认的作用域是 window,当我们没有显式声明变量时,变量则会直接挂在 window 对象上,而严格模式下是不允许的

"use strict"
myname='yimwu'
console.log(myname) // Uncaught ReferenceError: myname is not defined

2、禁止使用 with

with 通常被当做重复引用同一个对象中的多个属性的快捷方式,可以不需要重复引用对象本身,但是这种方式也带来了很大的隐患,令代码可维护性变差
在 with 中我们打印了 name、age,但是 name、age 并不是变量,而是 obj 的 key 值,这对于项目的可维护性增加了很多误导,如果多层嵌套后,会导致变量指向不明确,非常难以维护,因此严格模式下是禁止使用 with 的

"use strict"
var obj = {
  name: 'yimwu',
  age: 18
}
with(obj){
  console.log(name, age) // Uncaught SyntaxError: Strict mode code may not include a with statement
}

3、创建 eval

eval 可以说是一个非常危险的函数,许多 JS 相关的安全漏洞都跟 eval 有关,原因是它能够做到动态执行 JS 指令,这就给了黑客们许多“骚操作”的空间了,他们可以通过构造一些而已的 JS 指令,达到通过浏览器攻击服务器,窃取数据的效果,当开启严格模式后,eval 将有自己的作用域,达到作用域隔离的效果,能够避免一部分的安全问题

"use strict"
var myname = 'YI'
eval(`var myname = 'yimwu';console.log(myname)`) // yimwu
console.log(myname) // 'YI

4、禁止 this 指向 window

在普通模式下,默认的 this 都是指向 window,因此我们很经常会在不知不觉中就对 window 进行了某些修改,这其实是非常危险的,那么开启了严格模式后,将禁止 this 指向 window,而原本默认指向 window 的将变为指向 undefined

"use strict"
function fn(){
  console.log(this)
}
// fn() // undefined
// 通过 call、apply 能够修改 this 指向
fn.call({name: 'yimwu'})

5、函数参数不能重复

函数参数重复会导致该参数的传参无法读取,在开启严格模式后,将不允许这种形参写法,避免了无法读取的问题

"use strict"
function fn(name,name,age){
  console.log(name,age)
}
fn('yimwu',18) // Uncaught SyntaxError: Duplicate parameter name not allowed in this context

总结

通过简单的几道题的“拷问”,发现虽然写了挺久的 JS 了,但是对于 JS 的一些题目依然并没有完全的把我,可以说如果这是某次面试的面试题,那大概率这会是一块不可忽视的绊脚石,通过本次的学习,也算是把这块绊脚石“踢翻”了,也希望各位掘友们也能够通过这篇文章,清除掉一些 JS 相关的障碍,让我们一起冲吧,希望当潮水退去时,裸泳的人不是你我!

往期好文推荐

面试官:说说从输入 URL 到页面显示到底经历了什么,体现一下你的知识广度

面试官:作为前端,服务器相关了解多少?

面试官:HTTPS 采用的是对称加密还是非对称加密?具体说说其加密过程

面试官:说说 Cookie 和 Token 的区别?

面试官:网络安全了解多少,简单说说?(一)

面试官:网络安全了解多少,简单说说?(二)

面试官:网络安全了解多少,简单说说?(三)

面试官:网络安全了解多少,简单说说?(四)

面试官:网络安全了解多少,简单说说?(五)

面试官:网络安全了解多少,简单说说?(六)

面试官:网络安全了解多少,简单说说?(七)

面试官:网络安全了解多少,简单说说?(八)

浅尝 | 从 0 到 1 Vue 组件库封装

面试官:这么简单的正则表达式都不会?

Webpack 打包类库踩坑

面试官:你就只会 npm run build 吗?(Webpack 配置 Vue+Ts)

面试官:连VuePress都没搭过还说开发过组件库?(VuePress 搭建)

面试官: 连 Vue 视图更新都不会写?(Vue视图更新原理【一】)

面试官: 能不能手写 Vue 响应式?(Vue2 响应式原理【完整版】)

面试官:能不能手写 Vue3 响应式(Vue3 原理解析之响应系统的实现)

JS 优雅之道(JS 代码优化小 Tip)

面试官:你真的会用 SVG 吗? (SVG 应用实战)

面试官:说一下这个Loading动画实现思路 (CSS3 实现 Loading 动画)

JS 扫盲题 ( 面试题梳理系列 (一))

面试官:你确定你说的防抖不是节流吗?( 面试题梳理系列 (二))

面试官:除了 HTTP,你还用过什么通信协议?(Websocket 在数字孪生中的应用)

面试官:你真的理解 Event Loop 吗?( JS 事件循环 )

面试官:v-for 中 key 为什么不能用 index,从原理层面聊聊?

面试官:vue-router 的 hash 与 history 哪个模式会刷新页面?

面试官:说说你平时用过的自适应方案(数字孪生可视化自适应方案)

面试官:说一下如何优化过渡动画(数字孪生可视化过渡动画)

写在最后

博主接下来将持续更新好文,欢迎关注博主哟!!
如果文章对您有帮助麻烦亲点赞、收藏 + 关注和博主一起成长哟!!❤️❤️❤️