面试大纲

674 阅读31分钟

好好写代码,优质过人生


1、有几种方式可以实现继承

子类.prototype = new Person(); 实际子类公开父类私有&公开的属性和方法

// 冒充对象继承
function Parent () {
    this.name = 'lc';
}
Parent.prototype.getPro = function () {
    alert('原型函数');
}
function Child () {
    var items = new Parent();
    // 只能遍历公有属性&方法
    for (var i in items) {
        // hasOwnProperty 过滤掉原型链
        items.hasOwnProperty(i) ? this[i] = items[i] : '';
    }
}

执行后结果

// 混合继承【原型链&call】方式
function Parent () {
    this.name = 'lc';
    this.setName = function () {};
}
Parent.prototype.getPro = function () {
    alert('原型函数');
}
function Child () {
    // 子类构造函数继承父类公有属性&方法
    Parent.call(this);
}
Child.prototype = new Parent();
Child.prototype.constuctor = Child;

new Parent();
new Child();

执行后结果

// call+拷贝继承
function Parent() {
    this.name = 'lc';
}
Parent.prototype.getPro = function () {
    alert('原型函数');
}
function Child() {
    // 子类构造函数继承父类公有属性&方法
    Parent.call(this);
}
function extend (child, parent) {
    // 原型属性拷贝
    for (var i in parent) {
        child[i] = parent[i];
    }
}
extend(Child.prototype, Parent.prototype);
// 中间件继承
function Parent() {
    this.name = 'lc';
}
Parent.prototype.getPro = function () {
    alert('原型函数');
}
Child.prototype.__proto__ = Parent.prototype;
new Parent();
new Child();
// 寄生组合式继承
function inheritPrototype(child,parent){
	var prototype = Object.create(parent.prototype); // 创建对象
	prototype.constructor = child; // 增强对象
	child.prototype = prototype; // 指定对象
}
inheritPrototype(Child,Parent);

这个例子的高效率体现在他只调用了一次SuperType 构造函数,并且因此避免了在SubType.prototype上面创建不必要的、多余的属性。与此同时原型链还能保持不变,所以可以正常使用instanceof 和 isPrototypeOf() ,所以寄生组合继承是引用类型最理想的继承方法。

//经典继承,封装
function create(o) {
    function F(){}
    F.prototype=o;
    return new F(); 
}

var o={name:"张三",age:18};
var o2=create(o);//这样o2就继承自o了

与上面的大同小异,已知一个对象o,需要创建一个新的对象,这个新的对象继承自对象o。

2、call,apple,bind

  • call里this指向了call内的函数,this发生变化

3、用原型实现继承有什么缺点,怎么解决

寄生继承方式最优 xx.prototype = Create.obj(pp.prototype)

4、arguments

5、数据类型判断

6、作用域链、闭包、作用域

(function(){
    var a = 1;
    var foo = function(){
        console.log("haha");
    }
})();
console.log(window.a);
console.log(window.foo);

立即执行函数能够自动执行(function(){})()里面包裹的内容,能够很好地消除全局变量的影响。

7、Ajax的原生写法

8、对象深拷贝、浅拷贝

9、图片懒加载、预加载

11、this关键字

12、函数式编程

13、手动实现parseInt

14、为什么会有同源策略

15、怎么判断两个对象是否相等

16、事件模型

事件委托、代理 如何让事件先冒泡后捕获

17、window的onload事件和domcontentloaded

18、for...in迭代和for...of有什么区别

19、函数柯里化

20、call apply区别,原生实现bind

call,apply,bind 三者用法和区别:角度可为参数、绑定规则(显示绑定和强绑定),运行效率、运行情况。

21、async/await

22、立即执行函数和使用场景

23、设计模式(要求说出如何实现,应用,优缺点)/单例模式实现

24、iframe的缺点有哪些

25、数组问题

数组去重

数组常用方法 查找数组重复项 扁平化数组 按数组中各项和特定值差值排序

26、BOM属性对象方法

27、服务端渲染

28、垃圾回收机制

内存泄漏:全局变量造成内存泄漏、未销毁的定时器和回调函数、闭包造成内存泄漏

29、eventloop

进程和线程 任务队列

30、如何快速让字符串变成已千为精度的数字

  • iframe的缺点有哪些

请说明.forEach循环和.map()循环的主要区别,它们分别在什么情况下使用?

vue

1. 什么是Vue的双向数据绑定?如何实现的?

答:Vue的双向数据绑定是指视图(模板)层和数据层之间的双向关联,当数据层的数据发生改变时,视图也相应地更新,反之亦然。实现双向绑定的核心是使用Object.defineProperty方法,将数据对象的属性转化为getter和setter,通过getter获取属性值,通过setter更新视图。

2. Vue的父子组件通信有哪些方式?

Vue的父子组件通信一般采用props和$emit方法。

  • props: 父组件通过props向子组传递数据,子组件中使用props接收数据。父组件更新props数据时,子组件也会相应地更新视图。

  • emit:子组件通过emit: 子组件通过emit触发自定义事件并向父组件传递数据,父组件通过v-on监听子组件触发的事件,并在回调函数中处理数据。

  • $attrs$listeners,新增了inheritAttrs选项

现有3个嵌套组件,A->B,B->C。  A组件与C组件通信,我们有多少种解决方案?

  1. 我们使用vuex来进行数据管理,依赖于vuex我们可以一次改变,任何一个组件中都能获取。但是如果多个组件共享状态比较少,使用vuex过于麻烦和难以维护。element-ui中大量采用此方法。
  2. 自定义vue bus事件总线,原理类似vuex,使用特别简单。bus适合碰到组件跨级兄弟组件等无明显依赖关系的消息传递,原生app开发中经常用到,但是缺点是bus破坏了代码的链式调用,大量的滥用将导致逻辑的分散,出现问题后很难定位,降低了代码可读性。
  3. 使用B来做中转,A传递给B,B再给C**,**这是最容易想到的方案,但是如果嵌套的组件过多,需要传递的事件和属性较多,会导致代码繁琐,代码维护困难。

对于我们这种情况,3种方式都有局限性

在vue2.4中,为了解决该需求,引入了$attrs$listeners,新增了inheritAttrs选项。我们只需要在B组件中对引入的C组件增加下面两个属性即可绑定所有的属性和事件。

3. Vue的路由是如何实现的?

答:Vue的路由采用Vue Router来实现。Vue Router基于Vue.js开发,提供了一个可以声明式定义路由映射的机制,并且可以支持多种路由模式(Hash模式、History模式、Abstract模式等),对Single Page Application (SPA)开发非常友好。

4. Vue的计算属性和方法有什么区别?

答:Vue的计算属性和方法都可以用来处理数据并返回一个新值,但计算属性具有缓存机制,只有在相关依赖发生变化时才会重新计算。而方法则不具备缓存机制,每次渲染都会重新执行。

5. Vue的生命周期钩子函数有哪些?分别在什么时候执行?

答:Vue的生命周期钩子函数包括:beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed。执行顺序如下:

  • beforeCreate: 在实例创建之初完成,当前data和methods属性还未被初始化。

  • created:在实例创建完成后立即调用,可以调用data和methods等属性。

  • beforeMount: 在挂载之前调用。

  • mounted:Dom挂载完成后调用,在这个生命周期函数内,可以访问到我们所有Dom元素、Dom节点等。

  • beforeUpdate: 当数据发生改变时,触发更新之前调用。

  • updated: 数据更新之后触发。

  • beforeDestroy: 实例销毁之前调用,此时实例仍可被访问。

  • destroyed: 实例销毁之后调用,此时实例已经不可被访问了。

6. Vue中key有什么作用?

答:在Vue中使用key主要是为了更好地管理可复用的元素。当一个元素切换出现在同一个位置时,不同于删除和重新创建一个元素,Vue会尝试就地复用这个元素,并通过修改它内部的属性来使它匹配新的数据。如果没有key,则会出现不必要的更新或者错误。因此,在使用v-for循环可复用的元素时,应该为其添加唯一key值。

7. Vue中如何避免组件重复渲染?

答:在Vue渲染时,会进行一系列优化操作,尽量避免重复渲染组件。但是如果需要手动优化组件渲染,则可以采用以下方案:

  • shouldComponentUpdate:该钩子函数能够控制组件是否进行更新,在该函数中返回false可以阻止组件重新渲染。

  • 使用v-once:该指令只渲染组件的第一次状态,并其缓存起来,在后续渲染

8.vue动态修改伪类样式的两种方法

  1. css中变量动态修改样式

image.png

url图片地址修改样式

topLogo = 'edu-wenku.bdimg.com/v1/pc/VIP/d…'

image.png

image.png

  1. js动态修改伪类样式

image.png

9.vue不能watch数组变化、对象变化

deep的意思就是深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器,但是这样性能开销就会非常大了,任何修改obj里面任何一个属性都会触发这个监听器里的 handler。

1)优化到对象某个属性的监听

image.png

2)数组无法监听解决方案

this.$set(arr, index, newVal);

image.png

使用临时变量直接赋值的方式,原理与直接赋值数组一样

image.png

3)对象无法监听解决方案

vue 不能监听对象属性的添加、修改、删除

image.png

  1. 使用 this.$set(object, key, value)

使用深度监听 deep: true,只能监听原有属性的变化,不能监听增加的属性

image.png

  1. 使用 Object.assign 方法,直接赋值的原理监听(最推荐的方法)

image.png

性能

1. 什么是前端性能优化?有哪些方法和工具可以用来提高性能?

前端性能优化是指通过各种手段来提高网站或应用的响应速度、加载速度、页面渲染速度、用户体验等方面的性能。

是常见的前端性能优化方法和工具:

  1. 减少HTTP请求次数:合并CSS和JS文件、压缩图片等。 2.存数据:使用浏览器缓存或服务器缓存来提高页面加载速度。
  2. 减少DOM操作:尽量减少DOM操作,因为它们通常是开销最大的。
  3. 压缩和优化代码:使用minification、uglification等工具来压缩代码大小,减少下载。
  4. 使用CDN:使用CDN来加速文件的下载和页面的加载。
  5. 异步加载资源:使用异步加载技术来提高页面渲染速度和响应速度。 7 减小文件大小:使用处理器进行图片压缩、字体子集化等技术来减小文件大小。
  6. 使用HTTP/2:使用HTTP/2协议来提高页面加载速度。
  7. 优化图片:使用WebP格式、延迟加载等技术优化图片加载速度。
  8. 监控和分析网站性能:使用工具如Google Analytics或Pingdom来监控和分析网站性能,找到瓶颈并进行优化。

2. 为什么要优化前端性能?有哪些影响前端性能的因素?

优化前端性能可以提高网站的加载速度和响应速度,从而提升用户的体验和满意度,进而提高网站的流量和转化率。

影响前端性能的因素很多,常见的包含:

  1. 网络延迟:网络延迟越大,网站的响应速度就越慢。
  2. 资源大小:大量的图片、视频、脚本和样式表等资源会增网站的加载时间。
  3. 网络带宽:访问网站的用户网络带宽越小,网站的加载速度就越慢。
  4. 外部资源:依赖外部资源的请求时间也会影响网站的加载速度。
  5. 缓存:浏览器缓存和CDN缓存是否开启、正确使用,会影响网站的加载速度。
  6. 脚本执行时间:脚本的执行时间过长会阻塞和延迟页面渲染。
  7. 代码优化:代码质量和结构对性能也有较大影响,如页面渲染时避免重排、重绘等。
  8. 设备性能:移动设备或低配电脑的处理能力有限,这也会影响网的性能。

3. 如何减少页面加载时间?可以通过哪些手段来实现?

减少页面加载时间可以提高网站的性能和用户体验,以下是一些有效的方法:

  1. 压缩代码和资源文件 使用代码和资源文件压缩工具(如Gzip)可以减少文件大小,从而加快下载和页面加载时间。
  2. 图片优化 适的图片格式和大小可以减少图片加载时间。可以使用图片压缩工具在不降低图片质量的情况下减小文件大小。
  3. 使用内容分发网络(CDN) 使用CDN可以加速资源文件的获取和加载,因为CDN服务器通常会存储网站内容的副本,并将其分发到用户所在地区最近的服务器上。
  4. 避免必要的HTTP请求 每个HTTP请求都需要时间来建立连接、发送请求和接收响应。因此,通过合并和压缩CSS和JavaScript文件、删除不必要的资源和文件等方法来减少HTTP请求可以减少页面加载时间。
  5. 代码优化 优化代码可以减少页面。例如,通过使用异步和延迟加载JavaScript文件、避免使用复杂的CSS选择器、减少DOM操作等方法可以提高性能。
  6. 使用浏览器缓存 使用浏览器缓存可以减少HTTP请求次数和页面加载时间。缓存通常用于存储静态资源文件,例如CSS、JavaScript、图像等,并且它们可以存储在浏览器中,直到它们被更新或过期。

通过上述手段的组合可以有效地降低页面加载时间,提高网站性能和用户体验。

4. 如何避免页面渲染的阻塞和卡顿?有哪些技术可以使用?

页面渲染的阻塞和卡顿通常是由于以下原因引起:

  1. 大量的JavaScript代码,如过多的计算和DOM操作;

  2. CSS渲染阻塞,如当CSS文件比较大或在JavaScript中动加载CSS时,会导致页面渲染的阻塞;

  3. 图片和其他资源的下载和加载,如当页面中有大量的图片、媒体文件等资源需要加载时,也会导致页面渲染的阻塞。 为了避免页面渲染的阻塞和卡顿,可以使用以下技术:

  4. 将JavaScript代码放在页面底部或使用defer/async属性加载,避免过多的计算和DOM操作;

  5. 使用CSS Sprites技术合并图片,减少请求次数和下载量;

  6. 将CSS文件放在head标签中,避免渲染阻塞;

  7. 使用CDN加速图片和其他资源的下载和加载;

  8. 使用懒加载技术,在用户浏览到相关内容时再进行下载和加载;

  9. 优化图片大小和格式,如使用WebP格式来替代JPEG和PNG7. 使用HTTP/2协议来加速资源的下载和加载;

  10. 使用浏览器缓存技术,避免重复下载相同的资源。

5. 如何利用浏览器缓存来提高性能?有哪些注意事项?

浏览器缓存是指在浏览器中缓存静态资源,例如图片、JavaScript、CSS等,以便下次访问同一网站时可以更快地加载页面。使用浏览器缓存可以提高网站的性能和用户体验。以下是一些利用浏览器缓存提高性能的方法和注意事项:

  1. 设置缓存控制头:将静态资源的缓存控制头设置为适合的时间,例如1个月或1年。这样可以确保浏览器能够在相当长的时间内缓存该资源。

  2. 使用版本化 URL:给静态资源添加版本号,例如wenku.baidu.com?fr=2。当更新资源时,更改版本号,这样浏览器可以强制刷新缓存。

  3. 利用CDN:使用内容分发网络(CDN)可以最大程度地减少网络延迟和增加响应速度。CDN会将静态资源存储在多个地理位置的服务器上,这样用户就可以从最接近他们的服务器中获取资源。

  4. 缩小HTML、CSS和JavaScript文件的大小:缩小文件的大小可以减少加载时间并提高网站的性能。

  5. 不要将可变数据缓存在浏览器中:例如用户信息、购物车等可变数据应该避免缓存在浏览器中,因为它们可能会随时更改并且数据更新不及时。

  6. 禁止缓存控制头:对于需要保密的数据(例如银行帐户信息)等,应为其设置禁止缓存控制头,确保用户每次访问网站时都会重新获取最新的数据。

  7. 监视缓存效果:最后,应该监视缓存效果并根据需要更改缓存策略。请注意,即使控制缓存头为一个月或一年,如果您频繁更改资源,则可能需要更短的时间来控制缓存头。

6. 如何优化图片和视频的加载和显示?有哪些技术可以使用?

优化图片和视频的加载和显示可以使用以下技术:

  1. 图片压缩:使用图片压缩工具可以减小图片的文件大小,提高加载速度。还可以使用现代格式如WebP,文件大小更小,可提高网页性能。

  2. 缓存机制:浏览器缓存机制能够在一定程度上减少图片视频的加载时间,尤其针对频繁访问的图片,可以采取本地缓存、CDN缓存等方式。

  3. 懒加载:懒加载是将网页中的图片或视频只在需要时才加载,而不是一开始就全部加载。这样可以减少页面的初始加载时间,提高用户体验。

  4. 图片瀑布流布局:利用瀑布流布局可以使页面中的图片排布更加美观,同时也能够避免网络瓶颈等问题导致加载时间长的情况。

  5. 优化视频编码格式:选择合适的视频编码格式和参数可以减小视频文件大小,提高视频观看体验。同时还可以通过预加载、暂停、播放等操作化视频的加载和显示。

7. 如何减少 HTTP 请求次数?有哪些工具可以使用来分析和优化请求次数?

减少 HTTP 请求次数的方法:

  1. 合并文件:将多个 CSS、JS 文件合并成一个文件,可以减少请求次数。

  2. 压缩文件:使用 Gzip 等压缩算法,可以减少文件大小,进而减少请求次数。

  3. 使用 CDN:通过使用 CDN(内容分发网络),可以将资源分布在全球各地的服务器上,减少请求时的延迟。

  4. 缓存:将静态资源缓存在客户端或者服务器上,不必每次请求时都重新获取。

  5. 图片优化:通过压缩图片、使用 WebP 格式等方法,可以减小图片大小,从而减少请求次数。

工具:

  1. Chrome 开发者工具:可以使用 Network 面板来分析 HTTP 请求次数以及优化请求。

  2. YSlow:是一个用于分析页面性能的浏览器插件,可以评估页面的加载速度,并给出优化建议。

  3. PageSpeed:是 Google 推出的一款网页加载度分析工具,可以评估网页的加载速度,并给出优化建议。

  4. WebPagetest:是一款在线的网页性能工具,可以测量页面加载时间,并给出优化建议。

8. 如何优化网站的响应速度?可以通过哪些方法来实现?

网站的响应速度是用户体验的重要因素之一,如果网站响应速度太慢,会影响用户留存和转化率。以下是优化网站响应速度的方法:

  1. 压缩文件大小:对于图片、CSS、JavaScript等文件,可以使用压缩工具来减小文件大小,从而加快加载速度。

  2. 避免使用过多的插件和脚本:过多的插件和脚本可能导致网站加载缓慢,建议尽量减少使用。

  3. 使用CDN加速:使用CDN(内容分发网络)可以将网站的内容缓存到全球各地的服务器上,用户访问时可以从离他们最近的服务器获取内容,加快加载速度。

  4. 优化图片:使用正确的图片格式,尽量压缩图片大小,控制图片的数量和分辨率。

  5. 使用缓存机制:浏览器缓存、服务器缓存等缓存机制可以减少重复请求,加快加载速度。

  6. 压缩HTML、CSS和JavaScript:通过压缩代码可以减少文件大小,从而提高加载速度。

7.减少HTTP请求次数:可以将多个CSS和JavaScript文件合并成一个文件,减少HTTP请求次数。

  1. 优化服务器配置:调整服务器配置也能够提高网站响应速度,例如启用Gzip压缩、启用HTTP/2等。

以上是一些常见的优化网站响应速度的方法,具体方法应根据网站情进行选择。

9. 如何对网页进行压缩和合并?有哪些工具可以使用来实现?

网页压缩和合并是一种优化网页性能的方法,可以减少页面加载时间,提高用户体验。下面介绍两种常用的工具来实现网页压缩和合并。

1 Gzip压缩

Gzip是一种常用的文件压缩格式,可以减小文件尺寸并加快下载速度。可以使用Web服务器软件(如Apache或Nginx)来启用Gzip压缩,并对网页内容进行压缩。这样,当浏览器请求页面时,服务器会自动压缩数据并将其发送给浏览器。目前,大部分现代浏览器都支持自动解压缩Gzip格式的数据。

  1. 文件合并

合并多个CSS或JavaScript文件为一个单独的文件可以减少HTTP请求并提高页面加载速度。可以使用工具如Grunt或Gulp来自动化合并文件,并将它们压缩成一个单独的文件。另一个工具是Webpack,它可以自动识别项目中使用到的所有依赖关系,并将它们打包成一个单独的文件。

通过使用Gzip压缩和文件合并等化技术,可以显著提高网页性能,并提高用户满意度。

10. 如何进行网站性能测试和分析?有哪些工具可以使用来评估网站的性能?

网站性能测试和分析是评估网站的速度、响应时间、稳定性和可靠性的过程。以下是进行网站性能测试和分析的步骤以及可以使用的具:

  1. 确定测试目标和场景:在开始测试之前,确定测试的目标,并创建测试场景,这将帮助您模拟不同的使用情况和流量模式。

  2. 选择适当的测试工具:选择适当的性能测试工具可以帮助您评估网站的性能。一些流行的性能测试工具包括:JMeter,LoadRunner,Gatling等。

  3. 进行负载测试:使用选定的工具制并执行负载测试场景,这有助于确定网站在负载下的响应时间,吞吐量和资源利用率等方面的性能4. 分析结果:根据测试结果,对网站进行分析。您可以使用工具进行分析,如New Relic,Splunk或AppDynamics等。

  4. 优化和改进:根据测试结果和分析,进行性能优化和改进。这可能涉及到缓存,压缩文件大小,管理数据库连接池等。

react

1. React的生命周期方法:考察面试者对React组件生命周期的理解和应用能力。

React组件生命周期指的是组件在各种状态下自动调用的一系列方法。理解React组件生命周期和应用能力对于开发React应用非常重要,可以帮助我们更好地管理组件的状态和行为,优化渲染性能,处理异步数据请求等。

React组件生命周期可以分为三个阶段:

  1. Mounting:组件被创建并添加到DOM中。
  2. Updating:组件的状态或props发生变化,重新渲染。
  3. Unmounting:组件从DOM中移除。

在每个阶段中,React会自动调用一些钩子函数(或称为生命周期方法)来提供我们机会去处理组件的行为。

Mounting阶段:

  1. constructor():组件被创建时调用,用于初始化状态和绑定事件处理函数。
  2. static getDerivedStateFromProps():在组件被挂载之前调用,返回新的状态对象或null,并将其与现有的状态合并。
  3. render():虚拟DOM树,描述组件的UI界面。
  4. componentDidMount():在组件被挂载后调用,获取异步数据、执行DOM操作等。

Updating阶段:

  1. static getDerivedStateFromProps():组件更新之前调用,返回新的状态对象或null,并将其现有的状态合并。
  2. shouldComponentUpdate():在更新之前调用,返回一个布尔值,指示组件是否应该渲染。如果需要,可以比较新和旧props和state。
  3. render():更新虚拟DOM树并返回组件UI界面。
  4. componentDidUpdate():在更新完成后调用,在此可以执行DOM操作和网络请求等。

Unmounting阶段:

  1. componentWillUnmount():在组件从DOM中移除之前调用,清理定时器、取消事件监听器等资源。

理解和应用React组件生命周期可以帮助我们更好地管理组件,比如避免不必要的渲染、优化性能、异步请求等。同时,在使用React相关库和框架时也需要了解相关的生命周期方法,以便更好地使用这些工具。

2. React的虚拟DOM:问及面试者如何使用虚拟DOM提高性能并减少浏览器重绘。

React采用了虚拟DOM的机制进行页面渲染。具体来说,从数据的变化到最终的页面渲染,React采用以下步骤:

  1. 页面中的组件中的数据发生改变,触发组件的render函数。
  2. 组件的render函数返回虚拟DOM树。
  3. React使用虚拟DOM树与之前的虚拟DOM树进行比较,得出两个虚拟DOM树之间的差异(reconciliation)。
  4. 根据差异更新实际DOM树,完成页面渲染。

使用虚拟DOM可以提高性能和减少浏览器重绘的方法有以下几种:

1 减少对实际DOM树的直接操作:虚拟DOM是在内存中创建的,可以避免直接操作实际DOM树,从而减少览器重绘。 2. 批量更新:React会在一次事件循环中批量更新多个组件的虚拟DOM树,从而减少不必要的计算和页面渲染次数。 3. 虚拟DOM树的diff算:React使用高效的diff算法比较新旧虚拟DOM树之间的差异,并只更新有化的部分,从而减少不必的页面渲染,提高性能。 4. 优化组件更新:React提供了shouldComponentUpdate函数,开发者可以在此函数中判断当前组件是否需要更新,避免不必要的虚拟DOM树比较和页面渲染。

3. React的状态管理库:涉及Redux、Mobx等状态管理库,考察面试者对状态管理的理解及应用能力。

React的状态管理库包括Redux、MobX、Flux、Reflux等。

Redux是一个非常流行的状态管理库,它是基于Flux架构的,用于管理React应用程序中的状态。Redux的核心思想将应用程序的状态存储在一个单一的JavaScript对象中,并通过Action与Reducer的组合来更新这个对象的值。

而MobX则是一个简单、可扩展且易于使用的状态管理库,它通过观察(Observables)和反应(Reactions)实现了数据的自动更新。

Flux是一种架构思想,由Facebook提出,它通过将应用程序分为多个部分来简化状态管理。Flux架构中包含四个主要部分:Dispatcher、Store、Action、View,其中Dispatcher负责将Action分发给Store,Store负责管理状态,Action则是描述状态变化的对象,View则是从Store中获取状态并渲染UI。

Reflux是基于Flux架构的一种简化实现,通过事件流来管理状态,它将Dispatcher替换为一个简单的EventEmitter,并将Store分解为多个小的Store,使得管理状态更加灵活。

4. React中的组件通信:问题包括父子组件通信、兄弟组件通信、跨级组件通信等。

React中的组件通信是实现组件间数据传递和交互的重要方式。常见的组件通信场景包括:

  1. 父子组件通信

父组件可以通过props将数据和回调函数传递给子组件。子组件可以通过调用props中的函数并传递参数来向父组件传递数据。

  1. 兄弟组件通信

兄弟组件之间不能直接通信,所以可以通过将数据和回调函数传递给共同的父组件,再由父组件分别向两个子组件传递数据。

  1. 跨级组件通信

跨组件通信需要借助React的Context API。通过在父组件中创建一个Context对象,并提供一个Provider组件和一个Consumer组件,可以将数据传递给后代组件。后代组件可以通过Consumer组件获取数据。

5. React中的一些问题:比如React的优点、如何优化React应用性能、React中的key属性等。

React的优点:

  1. 高效的DOM操作:React使用虚拟DOM(Virtual DOM)技术,通过在JavaScript中使用虚拟DOM来表示DOM结构,在每次更新时比较新旧虚拟DOM,然后根据差异进行最小化的DOM更新操作,从而提高渲染效率。

  2. 组件化开发:React提供了组件化开发模式,将UI设计和构建划分为组件,并以树形结构组合这些组件。通过组件化开发,代码可重用性更高,结构更加清晰明确。

  3. 声明式编程:React采用声明式编程模式,将UI描述成一个状态映射到视图的函数,而不是直接操作DOM来更新视图。有了这个特性,程序员可以更加专注于代码实现,而不是纠结于如何操作DOM。

  4. 社区支持:React有一个庞大的社区,提供了许多重要的第三方库和插件,如React Router、Redux、Material-UI等等。这些工具对于React应用开发、测试和优化都非常有帮助。

如何优化React应用性能:

  1. 使用PureComponent或shouldComponentUpdate生命周期方法:这些方法能够防止组件在没有任何改变的情况下触发渲染,从而提高性能。PureComponent会自动比较当前和下一个props和state的值是否改变,而shouldComponentUpdate需要手动实现比较逻辑。

  2. 使用React.memo:React.memo是一个高阶组件,用于针对函数组件进行优化。它能够缓存组件的结果,如果输入没有改变,则不需要重新渲染组件。

  3. 优化列表渲染:在列表渲染时,可以使用key属性来告诉React哪些元素是可以重复利用的。此外,在列表渲染中尽量减少嵌套组件或深层次的数据结构,这会导致大量的重复渲染。

  4. 按需加载:当页面内容过多时,可以通过按需加载组件或路由来提高性能。Webpack提供了代码分割的功能,能够将应用拆分成更小的包并延迟加载。

React的key属性:

key属性是React用于追踪列表元素的重要属性。当数组中的元素顺序改变、新增或删除时,React使用key属性来决定哪些元素需要重新渲染。kv文件类型

在列表渲染时使用key属性会带来显著的性能提升,因为它能够让React识别出哪些元素是可以重复利用的。不指定key属性,React会每次渲染都销毁所有旧元素并创建新元素,这会导致大量的性能问题。

key属性该是保证唯一性的字符串或数字。在列表渲染中,建议使用数据中的唯一标识符或数组索引作为元素的key值。

6. React Native:如果是React Native岗位,还会涉及React Native的原理、如何使用React Native实现某些功能等问题。

React Native是一种可以使用JavaScript编写原生应用的框架,可以实现许多功能。以下是一些演示如何使用React Native实现各种功能的示例:

  1. 展示数据列表:使用FlatList组件可以很方便地展示列表。FlatList可以优化数据展示,只渲染当前视口内的数据,从而提高性能。

  2. 触摸事件:React Native提供了多种Touch组件,例如TouchableNativeFeedback、TouchableOpacity和TouchableHighlight等。使用这些组件可以处理各种触摸事件,并为用户提供反馈。

3 网络请求:使用Fetch API可以轻松地进行网络请求,例如获取数据或上传文件等。Fetch API是用于现代浏览器和React Native的基本网络API。

  1. 调用原生模块:React Native提供了一个桥接机制,可以在JavaScript代码中调用原生模块。例如,在React Native应用中调用相机或地理位置等原生模块,就需要使用这个机制。

  2. 路由和导航:React Navigation是一个流行的第三方库,提供了方便的路由和导航。使用React Navigation可以快速构建具有导航功能的React Native应用。

  3. 持久存储:React Native提供了AsyncStorage API,用于在应用中进行持久存储。可以使用AsyncStorage存储应用的设置、用户信息等数据。

  4. 布局和样式:React Native采用Flexbox布局,非常适合移动设备的屏幕大小和方向变化。同时,React Native也支持CSS样式,使得开发者能够使用熟悉的CSS属性来设置样式。

  5. 动画:React Native提供了一组动画API,包括Animated和LayoutAnimation等。使用这些API可以轻松地创建各种动画效果,例如弹出菜单、滚动视图和平移等。

7. TypeScript:如果是用TypeScript开发React应用的岗位,则会有与TypeScript相关的问题。

TypeScript是一种静态类型语言,它可以在编译时检查代码错误,提高开发效率和代码质量。React是一个流行的JavaScript库,用于构建用户界面。TypeScript可以与React一起使用,以提供类型检和更好的开发体验。

以下是使用TypeScript开发React应用的步骤:

  1. 安装TypeScript和React

使用npm或yarn安装TypeScript和React:

npm install typescript react react-dom

或者

yarn add typescript react react-dom
  1. 初始化TypeScript配置文件

使用TypeScript的命令行工具tsc,初始化tsconfig.json文件:

tsc --init
  1. 配置tsconfig.json文件

编辑tsconfig.json文件,以启用React的支持和其他必要的配置:

{
  "compilerOptions": {
    "jsx": "react",
    "target": "es6",
    "module": "commonjs",
    "esModuleInterop": true,
    "Map": true
  },
  "include": ["src/**/*"]
}
  1. 创建React组件

使用TypeScript创建React组件,例如:

import React from 'react';

interface Props {
  name: string;
}

const Greeting: React.FC<Props> = ({ name }) => {
  return <div>Hello, {name}!</div>;
};

export default Greeting;

注意,我们使用了React.FC泛型函数组件类型,以确保组件有的props类型。

  1. 在应用程序中使用React组件

将React组件导入并在应用程序中使用,例如:

import React from 'react';
import ReactDOM from 'react-dom';
 Greeting from './Greeting';

ReactDOM.render(<Greeting name="Alice" />, document.getElementById('root'));

注意,我们使用了类型为“string”的“name”prop来渲染Greeting组件。

  1. 运行应用程序并检查类型错误

使用本地开发服务器(例如Webpack Dev Server)运行应用程序,并在浏览器中查看结果。检查控制台是否有任何类型错误。

算法

前端算法题通常包括字符串操作、数组操作、排序算法、递归算等等,涵盖了算法领域中的入门和进阶知识点。常见的前端算法题有如下几个:

1. 反转字符串

给定一个字符串,将其反转后输出。

2. 数组去重

给定一个数组,去除其中重复的元素。

3. 二分查找

给定一个已排序的数组和一个目标值,使用二分查找算法查找目标值是否存在于数组中。

4. 快速排序

给定一个数组,使用快速排序算法将其按照从小到大的顺序排列。

5. 深度优先搜索

给定一个图形结构,使用深度优先搜索算法遍历其中的所有节点。

6. 广度优先搜索

给定一个图结构,使用广度优先搜索算法遍历其中的所有节点。

7. 斐波那契数列

使用递归算法实现斐波那契数列。

8. 最长公共子序列

给定两个字符串,求这两个字符串最长公共子序列的长度。

9. 背包问题

给定一组物品和一个背包容量,求在背包容量限制下能够放置的最大价值物品。

10. LeetCode算法题

LeetCode是一个全球性的在线编程题库,其中包含了各种各样的算法题目,很多前端开发人员使用这些题目来提高自己的编程能力。

小程序

1. webview页—>小程序发送消息 , 小程序接收不到?

先使用 swan.webView.postMessage 发送实时消息时先排查开发流程是不是先通过小程序向 H5 发送消息,待 H5 收到消息后再向小程序发消息。

<view class="container">
    <include src="/template/pageloading.swan"/>
    <web-view
        s-if="url.length > 0"
        id="webviewmain"
        src="{{url}}"
        bindmessage="postMessageHandle">
    </web-view>
</view>
launchPage({
     data:{
         webViewContext: {} // webview通信上下文
     },
     onLoad(options) {
        // 初始化时就创建通信上下文
        this.createWebViewContext();
     },
     // 初始化通信上下文
    createWebViewContext() {
       // [Tips: swan.createWebViewContext方法参数是webview 组件中 id 属性的值]
        const webViewContext = swan.createWebViewContext('webviewmain');
        this.setData({
            webViewContext
        });
        webViewContext.postMessage({
            data: 'init_ctx',
        });
    },
    postMessageHandle(e) {
        //小程序接收h5传递的信息
        console.log(e.detail.data);
    }
 })

2. 小程序向webview页发送消息,发不出去?

  • 先看api是否需要鉴权
  • 再看api对应的suc和err回调状态
  • 对比文档查看是否漏传参
<view class="container">
    <include src="/template/pageloading.swan"/>
    <web-view
        s-if="url.length > 0"
        id="viewmain"
        src="{{url}}"
        bindmessage="postMessageHandle">
    </web-view>
</view>
const webViewContext = swan.createWebViewContext('viewmain');
webViewContext.postMessage({
    data: {
        message: '1'
    },
    success: res => {
        console.log('发送消息成功');
    },
    fail: err => {
        console.log('发送消息失败');
    },
    complete: res => {
        console.log('发送消息完成');
    }
});

3. input属性focus失效问题

1)先这样看看:在开发工具中不生效,但在手机真机调试时可以生效;

2)不好使后,再排查输入框样式问题,是否被其他元素覆盖;

3)不好使后,试试setData回调函数中执行focus:true赋值,并增加setTimeout兼容ios系统调起软键盘所用时间

 this.setData({
    focus:true
  })
  
    this.setData({
      focus:false
    },()=>{
      setTimeout(()=>{
        this.setData({
          focus:true
        })
      },500)
      
    })

4.webview页ios调起输入软键盘后,右上角系统菜单弹窗调不起?

  • ios/android 两端调起软键盘原理不同导致表现不同,需做兼容处理。

image.png www.5imoban.net/jiaocheng/h…

5.ios唤起软键盘后,页面fixed元素失效,跟随页面滚动

ios认为用户更希望的是元素随着滚动而移动,所以软键盘唤起后页面 fixed 元素失效变成 absolute 定位,所以当页面超过一屏且滚动时,失效的 fixed 元素就会跟随滚动,需做兼容处理。

juejin.cn/post/684490…

6. 什么是小程序的生命周期?有哪些不同的生命周期函数?

7. 如何优化小程序的性能?

8. 如何实现程序之间的通信?

9. 怎么理解小程序中的双向数据绑定?和 Vue 的双向数据绑定有什么不同?

10. 小程序和 H5 页面的区别有哪些?在开发中应该如何选择?

11. 如何进行小程序的错误处理和调试?

12. 什么是微信小程序的“总控”概念?如何使用总控来优化小程序性能?

13. 小程序如何处理复杂业务逻辑和数据存储需求?

14. 如何进行小程序的用户数据统计和分析?

攻击

1.前端常见的安全策略?

    1.定期请第三方机构做安全性测试,漏洞扫描
    2.使用第三方开源库做上线前的安全测试,可以考虑融合到 CI3.默认项目中设置对应的 Header 请求头,如 X-XSS-Protection、 X-Content-Type-Optioens 、X-Frame-Options HeaderContent-Security-Policy

2.前端安全XSS、CSRF


服务端与网络

1.前端持久化的方式、区别

cookie 限制存储大小4k 、sessionStorage 窗体会话结束,数据清空 、localStorage 永久存储,复杂数据关系不支持

2.DNS是怎么解析的

  • ajax、 axios库

  • tcp三次握手,四次挥手流程

  • 跨域

  • Http请求中的keep-alive有了解吗

  • 即时通信,除了Ajax和websocket

  • 模块化,commonJS,es6,cmd,amd