js的一些题

ES6 代码转成 ES5 代码的实现思路是什么

题目说的是 ES6,所以不考虑 .jsx、.ts 这类 js 拓展语言。
ES6 转 ES5 目前行业标配是用 Babel,转换的大致流程如下:

1. 解析:解析代码字符串,生成 AST;
2. 转换:按一定的规则转换、修改 AST;
3. 生成:将修改后的 AST 转换成普通代码。
如果不用工具,纯人工的话,就是使用或自己写各种 polyfill 了。

随机生成一个长度为 10 的整数类型的数组,例如 [2, 10, 3, 4, 5, 11, 10, 11, 20],将其排列成一个新数组,要求新数组形式如下,例如 [[2, 3, 4, 5], [10, 11], [20]]

// 1. 随机数组
const arr = Array.from({ length: 10 }, () => Math.round(Math.random() * 9 + 1));
console.log('原始数据',arr);
// 2. 排序
const sortArr = arr.sort((a,b)=>a-b)
// 3. 组合
const newArr = [];
for (let i = 1, prevStart = undefined; ; i++) {
  const start = prevStart === undefined ? sortArr.length - i : prevStart - i;
  if (start < 0) break;
  newArr.unshift(sortArr.slice(start, prevStart));
  prevStart = start;
}
console.log('新数据',newArr);

如何把一个字符串的大小写取反(大写变小写小写变大写),例如 ’AbC' 变成 'aBc' 。

function overturnStr(str) {
  let newStr = ''
  for (let s of str) {
    if (s.toUpperCase() === s) {
      newStr += s.toLowerCase()
    }
    newStr += s.toUpperCase()
  }
  return newStr
}

介绍下 webpack 热更新原理,是如何做到在不刷新浏览器的前提下更新页面的

1.当修改了一个或多个文件;
2.文件系统接收更改并通知webpack;
3.webpack重新编译构建一个或多个模块,并通知HMR服务器进行更新;
4.HMR Server 使用webSocket通知HMR runtime 需要更新,HMR运行时通过HTTP请求更新jsonp;
5.HMR运行时替换更新中的模块,如果确定这些模块无法更新,则触发整个页面刷新。

为什么普通 for 循环的性能远远高于 forEach 的性能,请解释其中的原因。

* for 循环没有任何额外的函数调用栈和上下文;

* forEach函数签名实际上是

array.forEach(function(currentValue, index, arr), thisValue)

它不是普通的 for 循环的语法糖,还有诸多参数和上下文需要在执行的时候考虑进来,这里可能拖慢性能;

介绍下 BFC、IFC、GFC 和 FFC

  • BFC(Block formatting contexts):块级格式上下文
    页面上的一个隔离的渲染区域,那么他是如何产生的呢?可以触发BFC的元素有float、position、overflow、display:table-cell/ inline-block/table-caption ;BFC有什么作用呢?比如说实现多栏布局’

  • IFC(Inline formatting contexts):内联格式上下文
    IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC中的line box一般左右都贴紧整个IFC,但是会因为float元素而扰乱。float元素会位于IFC与与line box之间,使得line box宽度缩短。 同个ifc下的多个line box高度会不同
    IFC中时不可能有块级元素的,当插入块级元素时(如p中插入div)会产生两个匿名块与div分隔开,即产生两个IFC,每个IFC对外表现为块级元素,与div垂直排列。
    那么IFC一般有什么用呢?
    水平居中:当一个块要在环境中水平居中时,设置其为inline-block则会在外层产生IFC,通过text-align则可以使其水平居中。
    垂直居中:创建一个IFC,用其中一个元素撑开父元素的高度,然后设置其vertical-align:middle,其他行内元素则可以在此父元素下垂直居中。

  • GFC(GrideLayout formatting contexts):网格布局格式化上下文
    当为一个元素设置display值为grid的时候,此元素将会获得一个独立的渲染区域,我们可以通过在网格容器(grid container)上定义网格定义行(grid definition rows)和网格定义列(grid definition columns)属性各在网格项目(grid item)上定义网格行(grid row)和网格列(grid columns)为每一个网格项目(grid item)定义位置和空间。那么GFC有什么用呢,和table又有什么区别呢?首先同样是一个二维的表格,但GridLayout会有更加丰富的属性来控制行列,控制对齐以及更为精细的渲染语义和控制。

  • FFC(Flex formatting contexts):自适应格式上下文
    display值为flex或者inline-flex的元素将会生成自适应容器(flex container),可惜这个牛逼的属性只有谷歌和火狐支持,不过在移动端也足够了,至少safari和chrome还是OK的,毕竟这俩在移动端才是王道。Flex Box 由伸缩容器和伸缩项目组成。通过设置元素的 display 属性为 flex 或 inline-flex 可以得到一个伸缩容器。设置为 flex 的容器被渲染为一个块级元素,而设置为 inline-flex 的容器则渲染为一个行内元素。伸缩容器中的每一个子元素都是一个伸缩项目。伸缩项目可以是任意数量的。伸缩容器外和伸缩项目内的一切元素都不受影响。简单地说,Flexbox 定义了伸缩容器内伸缩项目该如何布局

数组里面有10万个数据,取第一个元素和第10万个元素的时间相差多少

JavaScript 没有真正意义上的数组,所有的数组其实是对象,其“索引”看起来是数字,其实会被转换成字符串,作为属性名(对象的 key)来使用。所以无论是取第 1 个还是取第 10 万个元素,都是用 key 精确查找哈希表的过程,其消耗时间大致相同。

输出以下代码运行结果

// example 1
var a={}, b='123', c=123;  
a[b]='b';
a[c]='c';  
console.log(a[b]);

---------------------
// example 2
var a={}, b=Symbol('123'), c=Symbol('123');  
a[b]='b';
a[c]='c';  
console.log(a[b]);

---------------------
// example 3
var a={}, b={key:'123'}, c={key:'456'};  
a[b]='b';
a[c]='c';  
console.log(a[b]);

这题考察的是对象的键名的转换。

  • 对象的键名只能是字符串和 Symbol 类型。
  • 其他类型的键名会被转换成字符串类型。
  • 对象转字符串默认会调用 toString 方法。
// example 1
var a={}, b='123', c=123;
a[b]='b';

// c 的键名会被转换成字符串'123',这里会把 b 覆盖掉。
a[c]='c';

// 输出 c
console.log(a[b]);
// example 2
var a={}, b=Symbol('123'), c=Symbol('123');

// b 是 Symbol 类型,不需要转换。
a[b]='b';

// c 是 Symbol 类型,不需要转换。任何一个 Symbol 类型的值都是不相等的,所以不会覆盖掉 b。
a[c]='c';

// 输出 b
console.log(a[b]);
// example 3
var a={}, b={key:'123'}, c={key:'456'};

// b 不是字符串也不是 Symbol 类型,需要转换成字符串。
// 对象类型会调用 toString 方法转换成字符串 [object Object]。
a[b]='b';

// c 不是字符串也不是 Symbol 类型,需要转换成字符串。
// 对象类型会调用 toString 方法转换成字符串 [object Object]。这里会把 b 覆盖掉。
a[c]='c';

// 输出 c
console.log(a[b]);

Vue 的父组件和子组件生命周期钩子执行顺序是什么

  • 加载渲染过程
    父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
  • 子组件更新过程
    父beforeUpdate->子beforeUpdate->子updated->父updated
  • 父组件更新过程
    父beforeUpdate->父updated
  • 销毁过程
    父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

打印出 1 - 10000 之间的所有对称数

例如:121、1331 等

[...Array(10000).keys()].filter((x)=>{
  return x.toString().length > 1 && x === Number(x.toString().split('').reverse().join(''))
})
点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注