哪些彩票网站可做代理赚钱,公司网站首页导航html,修邦建设网站,wordpress模版seo文章同步在公众号#xff1a;萌萌哒草头将军#xff0c;欢迎关注#xff01;#xff01;#xff01;
一面
es6新特性有哪些
新增了let、const关键字替换var声明变量#xff0c;因为var会导致变量提升#xff0c;在申明之前可以访问变量。新增了箭头函数#xff0c;新…文章同步在公众号萌萌哒草头将军欢迎关注
一面
es6新特性有哪些
新增了let、const关键字替换var声明变量因为var会导致变量提升在申明之前可以访问变量。新增了箭头函数新增了promise、sync await、还有一些高级特性比如像proxy。
Promise静态方法有哪些
any、 race、 all等reject resolve也是静态方法。
然后面试官让我说下all的用法。我当时说多个Promise全部执行为才会调用all。但是面试官让我手写下用法我给写错了面试官耐心的引导我写出正确的正确如下
Promise.all([new Promise(), new Promise(), new Promise()]).then(values console.log(values)).catch(err console.log(err))这时面试官又问我如果把catch里的方法。作为then里的第二个参数和现在的写法有啥区别吗
Promise.all([new Promise(), new Promise(), new Promise()]).then(values console.log(values),err console.log(err))如果任何一个Promise被拒绝会调用then的第二个参数而不会触发catch因为错误在then中已经处理了。
普通函数和箭头函数的区别
普通函数内部是有this指向的指向调用函数的对象箭头函数本身是没有的里面的this是箭头函数第一个有this的父作用域里的this。
例如
let obj {}
function fun1 () {console.log(this)
}
const fun2 () console.log(this)obj.a fun1 // this指向obj
obj.b fun2 // this指向window接着面试官又问了我一个问题箭头函数的this是调用的时候确定的还是定义的时候确定的
我回答调用的时候调用的时候对象属于哪个作用域就是确定为哪个。
实际是定义的时候确定的。
map和set的作用
你知道map和set的作用吗
我回答了一半Map允许使用任意类型的键包括对象而对象的键只能是字符串或符号。
其实除此之外Map保留键值对的插入顺序遍历时按插入顺序返回。Map在增删查操作上有更好的性能特别是当键不是字符串时。
Set自动去除重复元素确保集合内的值唯一Set也提供了更高效的值查找、添加和删除操作。
js类定义静态方法
使用static关键字
js继承类怎么在方法内部调用方法
class A {a() {console.log(Method a from class A);}
}
class B extends A {b() {// this.a()super.a()}
}const instance new B();
instance.b(); // 输出: Method a from class Ats的泛型
有个加法函数有两个参数参数类型和返回值类型始终一致string或者number怎么实现我说可以用泛型实现。
const add T extends number | string(a: T, b: T): T a b返回值的类型可以不写因为会自动推断
然后面试官问我还有别的方法可以实现吗我想了半天说没有。
其实还有别的方法利用函数重载机制。
function add(a: number, b: number): number;
function add(a: string, b: string): string;
function add(a: any, b: any): any {return a b;
}ts参数可选
可以使用?指定可选或者使用工具函数指定可选。Omit
怎么防止多个文件打包进去多余的js和类按需加载
分割代码多使用动态import语句
const PageA lazy(() import(./Module/PageA))使用tree-shaking优化不过需要使用ESModule而不是CommondJS。tree-shaking可以通过AST语法树分析代码中没有使用的模块或者无用代码的导出。
按需引入代码而不是引入所有
import { Button } from antd/lib/Button下面的代码有啥问题怎么修复
function C () {const [p, setP] useState(10)return Page p{[10, 20,]} onChange{(v) {setP(v); fetch(p)}} /
}发送请求时都是使用上次的值而不是最新值这是因为useState更新值时是异步的。react会进行一次批处理优化解决方法有两种
// 方法1
function C () {const [p, setP] useState(10)return Page p{[10, 20,]} onChange{(v) {setP(v); fetch(v)}} /
}
//方法2
function C () {const [p, setP] useState(10)useEffect(() fetch(p), [p]}return Page p{[10, 20,]} onChange{(v) {setP(v)}} /
}二面
找代码问题
聊完我的项目经历后立马问我下面的代码会出现什么问题怎么解决。
function Counter() {const [count, setCount] useState(0);useEffect(() {const id setInterval(() {setCount(count 1);}, 1000);return () clearInterval(id);}, []);return h1{count}/h1;
}上面的代码更新count有问题因为每次更新count都使用旧的值而不是最新的
setCount((prevCount) prevCount 1); // 使用函数式更新接着又给我下面的例子问我有啥问题
function Counter() {const [count, setCount] useState(0);const [step, setStep] useState(1);useEffect(() {const id setInterval(() {setCount(c c step);}, 1000);return () clearInterval(ref.current);}, [step]);return (h1{count}/h1input value{step} onChange{e setStep(Number(e.target.value))} //);
}上面的组件出现的问题是每次当step的值发生改变时都会重新创建新的定时器
修改方法如下
function Counter() {const [count, setCount] useState(0);const [step, setStep] useState(1);const ref useRef(null)useEffect(() {if (!ref.current) {ref.current setInterval(() {setCount(c c step);}, 1000);}// const id setInterval(() {// setCount(c c step);// }, 1000);return () clearInterval(ref.current);}, [step]);return (h1{count}/h1input value{step} onChange{e setStep(Number(e.target.value))} //);
}实现ts里的Picker 和 Omit
这个问题我当时是不会的说实话这两个工具函数我用的都很少更别说实现了
webpack 和 vite 的 tree chunking的区别
tree chunking是一种清除无用代码的方案主要是通过分析静态的代码导出和导入关系寻找无用代码然后删除它不将它打包从而优化代码体积webpack需要开启es module并且开启optimization选项而vite天生就是支持es module的不过vite是使用依赖的es模块加载机制优化的。
webpack loader 和 plugin 的区别
功能区别Webpack原生只能理解js和JSON文件而Loader扩展了其能力使其能够处理非js文件Loader是文件级别的转换工具允许你在模块打包时对文件进行处理。plugin是对Webpack的整个构建过程进行扩展和增强.
原理的区别webpack的loader拿到的是特定类型文件而plugin可以根据hook处理webpack的各个流程。另外插件的本质是个是个带有apply方法的类apply方法中参数是complier对象可以通过这个对象提供的hook监听特定文件的变化进行编译。而loader是个函数参数是匹配到的文件源码。
module.exports class MyPlugin {apply(compiler) {compiler.hooks.done.tap(MyPlugin, (Compilation) {console.log(MyPlugin: Compilation finished!);});}
}用法区别loader需要根据正则匹配特定的类型的文件plugin需要实例化插件
commondJS 和 ESModule 的区别
commondJS是动态的只有在运行时才能确定具体导入的内容而ESModule是静态的在编译时就能确定引入和导出的模块
commondJS导入使用的是requirerequire可以出现在代码任何地方所以是动态的导出使用exports或者module.exports
ESModule导入语句是importimport只能出现在文件顶部。所以是静态的import方法除外导出使用export
commondJS实际上是被包裹在一个函数中可以使用this而ESModule没有this
commondJS会缓存模块。重新加载返回的是缓存ESModule也是缓存后续的导入将共享相同的实例
下面的输出内容是啥
// a.js
const b require(./b);
console.log(exports.x);
exports.x x;
require(./c);// b.js
const a require(./a);
console.log(a);
a.x y;// c.js
const a require(./a);
console.log(a.x);输出结果如下
{}
undefined
x分析步骤
加载a.js首先遇到require(./b)它会开始加载b.js。此时a.js尚未完全加载完成它处于未完成的状态因此Node.js会将一个空的exports对象暴露给b.js
接着加载b.js在b.js中有const a require(./a)由于a.js还在加载中未完成所以 a 会是当前的未完成a.js的导出对象此时是空的 {}。所以执行console.log(a)打印结果为{} 接着执行a.x y这会修改a模块的导出内容将{} 变为 { x: y }。但是由于 a.js还未完成执行exports.x x; 还没有执行所以x暂时变为y。
然后回到a.js继续执行
首先执行console.log(exports.x)此时 exports 对象还没有被赋值exports.x是undefined。 然后执行exports.x x将a.js的exports对象更新为{ x: x }覆盖了之前b.js 中将x赋值为y的修改。
接着加载require(./c)开始加载 c.js。
在c.js中有const a require(./a)。由于a.js已经完成了加载因此a的值是最终导出的 exports对象{ x: x }。 执行console.log(a.x)此时a.x 是x所以会输出 x。
写一个加法函数sum支持sum(1)(2)(3,4)(5,6,7....), console.log(sum(1,2,3)(4)) 输出 10
我当时写完的函数是这样的虽然差不多意思但是不太对。有知道的大佬可以在告诉我下。
const sum (...args) {const add (x) {if (x undefined) {return args.reduce((a, b) a b, 0)} else {args.push(x)return add(...args)}}return add(...args)
}三面
简单问了下项目经历聊了下项目里的亮点四十分钟不到结束了。这里就不多赘述了。
总结
从结果来看虽然通过了但是真的觉得自己很菜很多底层的东西可能只是知其然并没有知其所以然。
虽然es6已经横空出世好多年了但是里面的内容真的搞懂的不是很多。所以后续还需要多翻书多研究细节。
最后希望这篇文章可以帮到找工作的同学也可以翻看我前面的几篇面试文章。
文章中出现错误的地方欢迎指正