1.display:none 与 visibility:hidden 的区别是什么?
display:none和visibility:hidden都可以实现元素在视窗的不可见,display:none不会保留元素的位置,结构发生了改变,所以触发了回流和重绘;visibility:hidden会保留元素的位置,结构没有发生改变,所以只是触发了重绘。
2.new 的原理是什么?通过 new 的方式创建对象和通过字面量创建有什么区别?
new的过程主要完成了以下操作
- 创建一个空对象
- 获取构造函数
- 设置空对象的原型
- 绑定 this 并执行构造函数
- 确保返回值为对象
完成以上步骤,我们可以自己模拟一个new
通过new创建的对象和通过字面量创建的对象本质上是一样的,字面量内部也是使用new来完成的。但是通过字面量的方式比较简单,也不用调用构造函数,性能较好,所以推荐使用字面量的方式。
3.前端路由原理?两种实现方式有什么区别?
前端路由本质就是监听 URL 的变化,然后匹配路由规则,显示相应的页面,并且无须刷新页面。目前前端使用的路由就只有两种实现方式:Hash 模式和History 模式。
Hash 模式
Hash模式会在请求的URL后拼接#,当 # 后面的哈希值发生变化时,可以通过 hashchange 事件来监听到 URL 的变化,从而进行跳转页面,并且无论哈希值如何变化,服务端接收到的 URL 请求永远是不包含#的URL。使用window.location.hash可以读取#后的内容。
History 模式
History 模式是 HTML5 新推出的功能,主要使用 history.pushState 和 history.replaceState 来改变URL。通过 History 模式改变 URL 同样不会引起页面的刷新,只会更新浏览器的历史记录。
- history.pushState:在history中新增一条记录,参数有三个。第一个参数是传入的数据,可以为空;第二参数修改的浏览器标题,可以为空;第三个参数是新的URL地址,不可以跨域。
- history.replaceState:在history中修改当前记录,参数和pushState一致。
当用户做出浏览器动作时,比如history.back()、history.forward()、history.go(),会触发 popState 事件,在popState事件里可以拿到路由信息,从而进行页面跳转。
两种模式对比
- Hash 模式只可以更改 # 后面的内容,History 模式可以通过 API 设置任意的同源 URL History 模式可以通过
- API 添加任意类型的数据到历史记录中,Hash 模式只能更改哈希值,也就是字符串 Hash
- Hash模式无需后端配置,并且兼容性好。History 模式在用户手动输入地址或者刷新页面的时候会发起 URL 请求,后端需要配置index.html 页面用于匹配不到静态资源的情况
4.node的优缺点以及适用场景
优点:
- 因为 Node 是基于事件驱动和无阻塞I/O的,所以非常适合处理并发请求,因此构建在Node 上的代理服务器相比其他技术实现(如Ruby)的服务器表现要好得多
- 与 Node 代理服务器交互的客户端代码是由 javascript语言编写的,因此客户端和服务器端技术统一
缺点:
- Node 是一个相对新的开源项目,所以不太稳定,更新比较快,向下不兼容
- Node适合于I/O密集型,不适合CPU密集型
解决方案:分解大型运算任务为多个小任务,使得运算能够适时释放,不阻塞I/O调用的发起 - 只支持单核CPU,不能充分利用CPU
- 可靠性比较低,一旦代码某个环节崩溃,整个系统都会崩溃
解决方案:- 使用Nginx进行反向代理,负载均衡,开多个进程,绑定多个端口
- 开多个进程监听同一个端口,使用cluster模块
- debug不太方便
使用场景:
- 实时应用:如在线聊天,实时通知推送等等(如 socket.io)
- 分布式应用:通过高效的并行 I/O 使用已有的数据
- 工具类应用:海量的工具,小到前端压缩部署(如 grunt),大到桌面图形界面应用程序
- 游戏类应用:游戏领域对实时和并发有很高的要求(如网易的 pomelo 框架)
- 总而言之,Node适合运用在高并发、I/O密集、少量业务逻辑的场景。
5.keep-alive 组件有什么作用?
vue在切换页面的时候会将原来的组件注销掉然后渲染新的组件,看似一样实则每次打开的都是新页面。如果我们需要在页面切换的时候,不让他重新渲染,就可以使用 keep-alive 组件包裹需要保存的组件。
对于 keep-alive 组件来说,它拥有两个独有的生命周期钩子函数,分别为 activated 和 deactivated 。
用 keep-alive 包裹的组件在切换时不会进行销毁,而是缓存到内存中并执行 deactivated 钩子函数,根据缓存渲染后会执行 actived 钩子函数。
假设一个页面比较长,每次切换重新渲染的话都要在页面顶端开始浏览,这对用户来说不太友好。如果我们使用keep-alive每次切换页面前将状态存到内存中,然后返回时再从内存中读取,每次打开都是上次浏览的地方,相对体验比较好
6.createElement 和 cloneElement 有什么区别?
React.createElement():JSX 语法就是用 React.createElement()来构建 React 元素的。它接受三个参数,第一个参数可以是一个标签名。如 div、span,或者 React 组件。第二个参数为传入的属性。第三个以及之后的参数,皆作为组件的子组件。
React.cloneElement()与 React.createElement()相似,不同的是它传入的第一个参数是一个 React 元素,而不是标签名或组件。新添加的属性会并入原有的属性,传入到返回的新元素中,而旧的子元素将被替换,旧元素的key和ref会保留。