好好写代码,优质过人生
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触发自定义事件并向父组件传递数据,父组件通过v-on监听子组件触发的事件,并在回调函数中处理数据。
-
$attrs和$listeners,新增了inheritAttrs选项
现有3个嵌套组件,A->B,B->C。 A组件与C组件通信,我们有多少种解决方案?
- 我们使用
vuex来进行数据管理,依赖于vuex我们可以一次改变,任何一个组件中都能获取。但是如果多个组件共享状态比较少,使用vuex过于麻烦和难以维护。element-ui中大量采用此方法。 - 自定义
vue bus事件总线,原理类似vuex,使用特别简单。bus适合碰到组件跨级兄弟组件等无明显依赖关系的消息传递,原生app开发中经常用到,但是缺点是bus破坏了代码的链式调用,大量的滥用将导致逻辑的分散,出现问题后很难定位,降低了代码可读性。 - 使用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动态修改伪类样式的两种方法
- css中变量动态修改样式
url图片地址修改样式
topLogo = 'edu-wenku.bdimg.com/v1/pc/VIP/d…'
- js动态修改伪类样式
9.vue不能watch数组变化、对象变化
deep的意思就是深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器,但是这样性能开销就会非常大了,任何修改obj里面任何一个属性都会触发这个监听器里的 handler。
1)优化到对象某个属性的监听
2)数组无法监听解决方案
this.$set(arr, index, newVal);
使用临时变量直接赋值的方式,原理与直接赋值数组一样
3)对象无法监听解决方案
vue 不能监听对象属性的添加、修改、删除
- 使用 this.$set(object, key, value)
使用深度监听 deep: true,只能监听原有属性的变化,不能监听增加的属性
- 使用 Object.assign 方法,直接赋值的原理监听(最推荐的方法)
性能
1. 什么是前端性能优化?有哪些方法和工具可以用来提高性能?
前端性能优化是指通过各种手段来提高网站或应用的响应速度、加载速度、页面渲染速度、用户体验等方面的性能。
是常见的前端性能优化方法和工具:
- 减少HTTP请求次数:合并CSS和JS文件、压缩图片等。 2.存数据:使用浏览器缓存或服务器缓存来提高页面加载速度。
- 减少DOM操作:尽量减少DOM操作,因为它们通常是开销最大的。
- 压缩和优化代码:使用minification、uglification等工具来压缩代码大小,减少下载。
- 使用CDN:使用CDN来加速文件的下载和页面的加载。
- 异步加载资源:使用异步加载技术来提高页面渲染速度和响应速度。 7 减小文件大小:使用处理器进行图片压缩、字体子集化等技术来减小文件大小。
- 使用HTTP/2:使用HTTP/2协议来提高页面加载速度。
- 优化图片:使用WebP格式、延迟加载等技术优化图片加载速度。
- 监控和分析网站性能:使用工具如Google Analytics或Pingdom来监控和分析网站性能,找到瓶颈并进行优化。
2. 为什么要优化前端性能?有哪些影响前端性能的因素?
优化前端性能可以提高网站的加载速度和响应速度,从而提升用户的体验和满意度,进而提高网站的流量和转化率。
影响前端性能的因素很多,常见的包含:
- 网络延迟:网络延迟越大,网站的响应速度就越慢。
- 资源大小:大量的图片、视频、脚本和样式表等资源会增网站的加载时间。
- 网络带宽:访问网站的用户网络带宽越小,网站的加载速度就越慢。
- 外部资源:依赖外部资源的请求时间也会影响网站的加载速度。
- 缓存:浏览器缓存和CDN缓存是否开启、正确使用,会影响网站的加载速度。
- 脚本执行时间:脚本的执行时间过长会阻塞和延迟页面渲染。
- 代码优化:代码质量和结构对性能也有较大影响,如页面渲染时避免重排、重绘等。
- 设备性能:移动设备或低配电脑的处理能力有限,这也会影响网的性能。
3. 如何减少页面加载时间?可以通过哪些手段来实现?
减少页面加载时间可以提高网站的性能和用户体验,以下是一些有效的方法:
- 压缩代码和资源文件 使用代码和资源文件压缩工具(如Gzip)可以减少文件大小,从而加快下载和页面加载时间。
- 图片优化 适的图片格式和大小可以减少图片加载时间。可以使用图片压缩工具在不降低图片质量的情况下减小文件大小。
- 使用内容分发网络(CDN) 使用CDN可以加速资源文件的获取和加载,因为CDN服务器通常会存储网站内容的副本,并将其分发到用户所在地区最近的服务器上。
- 避免必要的HTTP请求 每个HTTP请求都需要时间来建立连接、发送请求和接收响应。因此,通过合并和压缩CSS和JavaScript文件、删除不必要的资源和文件等方法来减少HTTP请求可以减少页面加载时间。
- 代码优化 优化代码可以减少页面。例如,通过使用异步和延迟加载JavaScript文件、避免使用复杂的CSS选择器、减少DOM操作等方法可以提高性能。
- 使用浏览器缓存 使用浏览器缓存可以减少HTTP请求次数和页面加载时间。缓存通常用于存储静态资源文件,例如CSS、JavaScript、图像等,并且它们可以存储在浏览器中,直到它们被更新或过期。
通过上述手段的组合可以有效地降低页面加载时间,提高网站性能和用户体验。
4. 如何避免页面渲染的阻塞和卡顿?有哪些技术可以使用?
页面渲染的阻塞和卡顿通常是由于以下原因引起:
-
大量的JavaScript代码,如过多的计算和DOM操作;
-
CSS渲染阻塞,如当CSS文件比较大或在JavaScript中动加载CSS时,会导致页面渲染的阻塞;
-
图片和其他资源的下载和加载,如当页面中有大量的图片、媒体文件等资源需要加载时,也会导致页面渲染的阻塞。 为了避免页面渲染的阻塞和卡顿,可以使用以下技术:
-
将JavaScript代码放在页面底部或使用defer/async属性加载,避免过多的计算和DOM操作;
-
使用CSS Sprites技术合并图片,减少请求次数和下载量;
-
将CSS文件放在head标签中,避免渲染阻塞;
-
使用CDN加速图片和其他资源的下载和加载;
-
使用懒加载技术,在用户浏览到相关内容时再进行下载和加载;
-
优化图片大小和格式,如使用WebP格式来替代JPEG和PNG7. 使用HTTP/2协议来加速资源的下载和加载;
-
使用浏览器缓存技术,避免重复下载相同的资源。
5. 如何利用浏览器缓存来提高性能?有哪些注意事项?
浏览器缓存是指在浏览器中缓存静态资源,例如图片、JavaScript、CSS等,以便下次访问同一网站时可以更快地加载页面。使用浏览器缓存可以提高网站的性能和用户体验。以下是一些利用浏览器缓存提高性能的方法和注意事项:
-
设置缓存控制头:将静态资源的缓存控制头设置为适合的时间,例如1个月或1年。这样可以确保浏览器能够在相当长的时间内缓存该资源。
-
使用版本化 URL:给静态资源添加版本号,例如wenku.baidu.com?fr=2。当更新资源时,更改版本号,这样浏览器可以强制刷新缓存。
-
利用CDN:使用内容分发网络(CDN)可以最大程度地减少网络延迟和增加响应速度。CDN会将静态资源存储在多个地理位置的服务器上,这样用户就可以从最接近他们的服务器中获取资源。
-
缩小HTML、CSS和JavaScript文件的大小:缩小文件的大小可以减少加载时间并提高网站的性能。
-
不要将可变数据缓存在浏览器中:例如用户信息、购物车等可变数据应该避免缓存在浏览器中,因为它们可能会随时更改并且数据更新不及时。
-
禁止缓存控制头:对于需要保密的数据(例如银行帐户信息)等,应为其设置禁止缓存控制头,确保用户每次访问网站时都会重新获取最新的数据。
-
监视缓存效果:最后,应该监视缓存效果并根据需要更改缓存策略。请注意,即使控制缓存头为一个月或一年,如果您频繁更改资源,则可能需要更短的时间来控制缓存头。
6. 如何优化图片和视频的加载和显示?有哪些技术可以使用?
优化图片和视频的加载和显示可以使用以下技术:
-
图片压缩:使用图片压缩工具可以减小图片的文件大小,提高加载速度。还可以使用现代格式如WebP,文件大小更小,可提高网页性能。
-
缓存机制:浏览器缓存机制能够在一定程度上减少图片视频的加载时间,尤其针对频繁访问的图片,可以采取本地缓存、CDN缓存等方式。
-
懒加载:懒加载是将网页中的图片或视频只在需要时才加载,而不是一开始就全部加载。这样可以减少页面的初始加载时间,提高用户体验。
-
图片瀑布流布局:利用瀑布流布局可以使页面中的图片排布更加美观,同时也能够避免网络瓶颈等问题导致加载时间长的情况。
-
优化视频编码格式:选择合适的视频编码格式和参数可以减小视频文件大小,提高视频观看体验。同时还可以通过预加载、暂停、播放等操作化视频的加载和显示。
7. 如何减少 HTTP 请求次数?有哪些工具可以使用来分析和优化请求次数?
减少 HTTP 请求次数的方法:
-
合并文件:将多个 CSS、JS 文件合并成一个文件,可以减少请求次数。
-
压缩文件:使用 Gzip 等压缩算法,可以减少文件大小,进而减少请求次数。
-
使用 CDN:通过使用 CDN(内容分发网络),可以将资源分布在全球各地的服务器上,减少请求时的延迟。
-
缓存:将静态资源缓存在客户端或者服务器上,不必每次请求时都重新获取。
-
图片优化:通过压缩图片、使用 WebP 格式等方法,可以减小图片大小,从而减少请求次数。
工具:
-
Chrome 开发者工具:可以使用 Network 面板来分析 HTTP 请求次数以及优化请求。
-
YSlow:是一个用于分析页面性能的浏览器插件,可以评估页面的加载速度,并给出优化建议。
-
PageSpeed:是 Google 推出的一款网页加载度分析工具,可以评估网页的加载速度,并给出优化建议。
-
WebPagetest:是一款在线的网页性能工具,可以测量页面加载时间,并给出优化建议。
8. 如何优化网站的响应速度?可以通过哪些方法来实现?
网站的响应速度是用户体验的重要因素之一,如果网站响应速度太慢,会影响用户留存和转化率。以下是优化网站响应速度的方法:
-
压缩文件大小:对于图片、CSS、JavaScript等文件,可以使用压缩工具来减小文件大小,从而加快加载速度。
-
避免使用过多的插件和脚本:过多的插件和脚本可能导致网站加载缓慢,建议尽量减少使用。
-
使用CDN加速:使用CDN(内容分发网络)可以将网站的内容缓存到全球各地的服务器上,用户访问时可以从离他们最近的服务器获取内容,加快加载速度。
-
优化图片:使用正确的图片格式,尽量压缩图片大小,控制图片的数量和分辨率。
-
使用缓存机制:浏览器缓存、服务器缓存等缓存机制可以减少重复请求,加快加载速度。
-
压缩HTML、CSS和JavaScript:通过压缩代码可以减少文件大小,从而提高加载速度。
7.减少HTTP请求次数:可以将多个CSS和JavaScript文件合并成一个文件,减少HTTP请求次数。
- 优化服务器配置:调整服务器配置也能够提高网站响应速度,例如启用Gzip压缩、启用HTTP/2等。
以上是一些常见的优化网站响应速度的方法,具体方法应根据网站情进行选择。
9. 如何对网页进行压缩和合并?有哪些工具可以使用来实现?
网页压缩和合并是一种优化网页性能的方法,可以减少页面加载时间,提高用户体验。下面介绍两种常用的工具来实现网页压缩和合并。
1 Gzip压缩
Gzip是一种常用的文件压缩格式,可以减小文件尺寸并加快下载速度。可以使用Web服务器软件(如Apache或Nginx)来启用Gzip压缩,并对网页内容进行压缩。这样,当浏览器请求页面时,服务器会自动压缩数据并将其发送给浏览器。目前,大部分现代浏览器都支持自动解压缩Gzip格式的数据。
- 文件合并
合并多个CSS或JavaScript文件为一个单独的文件可以减少HTTP请求并提高页面加载速度。可以使用工具如Grunt或Gulp来自动化合并文件,并将它们压缩成一个单独的文件。另一个工具是Webpack,它可以自动识别项目中使用到的所有依赖关系,并将它们打包成一个单独的文件。
通过使用Gzip压缩和文件合并等化技术,可以显著提高网页性能,并提高用户满意度。
10. 如何进行网站性能测试和分析?有哪些工具可以使用来评估网站的性能?
网站性能测试和分析是评估网站的速度、响应时间、稳定性和可靠性的过程。以下是进行网站性能测试和分析的步骤以及可以使用的具:
-
确定测试目标和场景:在开始测试之前,确定测试的目标,并创建测试场景,这将帮助您模拟不同的使用情况和流量模式。
-
选择适当的测试工具:选择适当的性能测试工具可以帮助您评估网站的性能。一些流行的性能测试工具包括:JMeter,LoadRunner,Gatling等。
-
进行负载测试:使用选定的工具制并执行负载测试场景,这有助于确定网站在负载下的响应时间,吞吐量和资源利用率等方面的性能4. 分析结果:根据测试结果,对网站进行分析。您可以使用工具进行分析,如New Relic,Splunk或AppDynamics等。
-
优化和改进:根据测试结果和分析,进行性能优化和改进。这可能涉及到缓存,压缩文件大小,管理数据库连接池等。
react
1. React的生命周期方法:考察面试者对React组件生命周期的理解和应用能力。
React组件生命周期指的是组件在各种状态下自动调用的一系列方法。理解React组件生命周期和应用能力对于开发React应用非常重要,可以帮助我们更好地管理组件的状态和行为,优化渲染性能,处理异步数据请求等。
React组件生命周期可以分为三个阶段:
- Mounting:组件被创建并添加到DOM中。
- Updating:组件的状态或props发生变化,重新渲染。
- Unmounting:组件从DOM中移除。
在每个阶段中,React会自动调用一些钩子函数(或称为生命周期方法)来提供我们机会去处理组件的行为。
Mounting阶段:
- constructor():组件被创建时调用,用于初始化状态和绑定事件处理函数。
- static getDerivedStateFromProps():在组件被挂载之前调用,返回新的状态对象或null,并将其与现有的状态合并。
- render():虚拟DOM树,描述组件的UI界面。
- componentDidMount():在组件被挂载后调用,获取异步数据、执行DOM操作等。
Updating阶段:
- static getDerivedStateFromProps():组件更新之前调用,返回新的状态对象或null,并将其现有的状态合并。
- shouldComponentUpdate():在更新之前调用,返回一个布尔值,指示组件是否应该渲染。如果需要,可以比较新和旧props和state。
- render():更新虚拟DOM树并返回组件UI界面。
- componentDidUpdate():在更新完成后调用,在此可以执行DOM操作和网络请求等。
Unmounting阶段:
- componentWillUnmount():在组件从DOM中移除之前调用,清理定时器、取消事件监听器等资源。
理解和应用React组件生命周期可以帮助我们更好地管理组件,比如避免不必要的渲染、优化性能、异步请求等。同时,在使用React相关库和框架时也需要了解相关的生命周期方法,以便更好地使用这些工具。
2. React的虚拟DOM:问及面试者如何使用虚拟DOM提高性能并减少浏览器重绘。
React采用了虚拟DOM的机制进行页面渲染。具体来说,从数据的变化到最终的页面渲染,React采用以下步骤:
- 页面中的组件中的数据发生改变,触发组件的render函数。
- 组件的render函数返回虚拟DOM树。
- React使用虚拟DOM树与之前的虚拟DOM树进行比较,得出两个虚拟DOM树之间的差异(reconciliation)。
- 根据差异更新实际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中的组件通信是实现组件间数据传递和交互的重要方式。常见的组件通信场景包括:
-
父子组件通信
父组件可以通过props将数据和回调函数传递给子组件。子组件可以通过调用props中的函数并传递参数来向父组件传递数据。
-
兄弟组件通信
兄弟组件之间不能直接通信,所以可以通过将数据和回调函数传递给共同的父组件,再由父组件分别向两个子组件传递数据。
-
跨级组件通信
跨组件通信需要借助React的Context API。通过在父组件中创建一个Context对象,并提供一个Provider组件和一个Consumer组件,可以将数据传递给后代组件。后代组件可以通过Consumer组件获取数据。
5. React中的一些问题:比如React的优点、如何优化React应用性能、React中的key属性等。
React的优点:
-
高效的DOM操作:React使用虚拟DOM(Virtual DOM)技术,通过在JavaScript中使用虚拟DOM来表示DOM结构,在每次更新时比较新旧虚拟DOM,然后根据差异进行最小化的DOM更新操作,从而提高渲染效率。
-
组件化开发:React提供了组件化开发模式,将UI设计和构建划分为组件,并以树形结构组合这些组件。通过组件化开发,代码可重用性更高,结构更加清晰明确。
-
声明式编程:React采用声明式编程模式,将UI描述成一个状态映射到视图的函数,而不是直接操作DOM来更新视图。有了这个特性,程序员可以更加专注于代码实现,而不是纠结于如何操作DOM。
-
社区支持:React有一个庞大的社区,提供了许多重要的第三方库和插件,如React Router、Redux、Material-UI等等。这些工具对于React应用开发、测试和优化都非常有帮助。
如何优化React应用性能:
-
使用PureComponent或shouldComponentUpdate生命周期方法:这些方法能够防止组件在没有任何改变的情况下触发渲染,从而提高性能。PureComponent会自动比较当前和下一个props和state的值是否改变,而shouldComponentUpdate需要手动实现比较逻辑。
-
使用React.memo:React.memo是一个高阶组件,用于针对函数组件进行优化。它能够缓存组件的结果,如果输入没有改变,则不需要重新渲染组件。
-
优化列表渲染:在列表渲染时,可以使用key属性来告诉React哪些元素是可以重复利用的。此外,在列表渲染中尽量减少嵌套组件或深层次的数据结构,这会导致大量的重复渲染。
-
按需加载:当页面内容过多时,可以通过按需加载组件或路由来提高性能。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实现各种功能的示例:
-
展示数据列表:使用FlatList组件可以很方便地展示列表。FlatList可以优化数据展示,只渲染当前视口内的数据,从而提高性能。
-
触摸事件:React Native提供了多种Touch组件,例如TouchableNativeFeedback、TouchableOpacity和TouchableHighlight等。使用这些组件可以处理各种触摸事件,并为用户提供反馈。
3 网络请求:使用Fetch API可以轻松地进行网络请求,例如获取数据或上传文件等。Fetch API是用于现代浏览器和React Native的基本网络API。
-
调用原生模块:React Native提供了一个桥接机制,可以在JavaScript代码中调用原生模块。例如,在React Native应用中调用相机或地理位置等原生模块,就需要使用这个机制。
-
路由和导航:React Navigation是一个流行的第三方库,提供了方便的路由和导航。使用React Navigation可以快速构建具有导航功能的React Native应用。
-
持久存储:React Native提供了AsyncStorage API,用于在应用中进行持久存储。可以使用AsyncStorage存储应用的设置、用户信息等数据。
-
布局和样式:React Native采用Flexbox布局,非常适合移动设备的屏幕大小和方向变化。同时,React Native也支持CSS样式,使得开发者能够使用熟悉的CSS属性来设置样式。
-
动画:React Native提供了一组动画API,包括Animated和LayoutAnimation等。使用这些API可以轻松地创建各种动画效果,例如弹出菜单、滚动视图和平移等。
7. TypeScript:如果是用TypeScript开发React应用的岗位,则会有与TypeScript相关的问题。
TypeScript是一种静态类型语言,它可以在编译时检查代码错误,提高开发效率和代码质量。React是一个流行的JavaScript库,用于构建用户界面。TypeScript可以与React一起使用,以提供类型检和更好的开发体验。
以下是使用TypeScript开发React应用的步骤:
- 安装TypeScript和React
使用npm或yarn安装TypeScript和React:
npm install typescript react react-dom
或者
yarn add typescript react react-dom
- 初始化TypeScript配置文件
使用TypeScript的命令行工具tsc,初始化tsconfig.json文件:
tsc --init
- 配置tsconfig.json文件
编辑tsconfig.json文件,以启用React的支持和其他必要的配置:
{
"compilerOptions": {
"jsx": "react",
"target": "es6",
"module": "commonjs",
"esModuleInterop": true,
"Map": true
},
"include": ["src/**/*"]
}
- 创建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类型。
- 在应用程序中使用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组件。
- 运行应用程序并检查类型错误
使用本地开发服务器(例如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 两端调起软键盘原理不同导致表现不同,需做兼容处理。
5.ios唤起软键盘后,页面fixed元素失效,跟随页面滚动
ios认为用户更希望的是元素随着滚动而移动,所以软键盘唤起后页面 fixed 元素失效变成 absolute 定位,所以当页面超过一屏且滚动时,失效的 fixed 元素就会跟随滚动,需做兼容处理。
6. 什么是小程序的生命周期?有哪些不同的生命周期函数?
7. 如何优化小程序的性能?
8. 如何实现程序之间的通信?
9. 怎么理解小程序中的双向数据绑定?和 Vue 的双向数据绑定有什么不同?
10. 小程序和 H5 页面的区别有哪些?在开发中应该如何选择?
11. 如何进行小程序的错误处理和调试?
12. 什么是微信小程序的“总控”概念?如何使用总控来优化小程序性能?
13. 小程序如何处理复杂业务逻辑和数据存储需求?
14. 如何进行小程序的用户数据统计和分析?
攻击
1.前端常见的安全策略?
1.定期请第三方机构做安全性测试,漏洞扫描
2.使用第三方开源库做上线前的安全测试,可以考虑融合到 CI 中
3.默认项目中设置对应的 Header 请求头,如 X-XSS-Protection、 X-Content-Type-Optioens 、X-Frame-Options Header、Content-Security-Policy 等
2.前端安全XSS、CSRF
服务端与网络
1.前端持久化的方式、区别
cookie 限制存储大小4k 、sessionStorage 窗体会话结束,数据清空 、localStorage 永久存储,复杂数据关系不支持
2.DNS是怎么解析的
- ajax、 axios库
- tcp三次握手,四次挥手流程
- 跨域
- Http请求中的keep-alive有了解吗
- 即时通信,除了Ajax和websocket
- 模块化,commonJS,es6,cmd,amd