【每日前端面经】2024-03-11
欢迎订阅我的前端面经专栏: 每日前端面经
本期题目来源: 牛客
Vue 响应式原理
Vue 独特的响应式系统:当 JavaScript 对象发生变化时,视图会自动更新。核心设计思想是数据劫持+观察者模式
- Vue 使用了一个名为 Observer 的类来实现数据劫持。当创建 Vue 实例时,Vue 会遍历传入的数据对象,对其进行递归遍历将其转化为响应式属性
- 当属性转化为响应式属性时,Vue 会为每个属性创建一个 Dep 依赖对象,用于收集当前属性的依赖关系
- 当访问一个响应式属性时,Vue 会在访问过程中收集依赖,将当前属性和对应的 Watcher 对象关联起来
- 当属性发生变化时,Vue 会通知该属性的 Dep 依赖对象,然后依赖对象遍历其依赖列表没通知每个依赖的 Watcher 对象进行更新操作
- 方法1:Object.defineProperty 实现
js
function render() {
console.log('模拟视图渲染')
}
let obj = [1, 2, 3]
let methods = ['pop', 'shift', 'unshift', 'sort', 'reverse', 'splice', 'push']
// 先获取到原来的原型上的方法
let arrayProto = Array.prototype
// 创建一个自己的原型 并且重写methods这些方法
let proto = Object.create(arrayProto)
methods.forEach(method => {
proto[method] = function() {
// AOP
arrayProto[method].call(this, ...arguments)
render()
}
})
function observer(obj) {
// 把所有的属性定义成set/get的方式
if (Array.isArray(obj)) {
obj.__proto__ = proto
return
}
if (typeof obj == 'object') {
for (let key in obj) {
defineReactive(obj, key, obj[key])
}
}
}
function defineReactive(data, key, value) {
observer(value)
Object.defineProperty(data, key, {
get() {
return value
},
set(newValue) {
observer(newValue)
if (newValue !== value) {
render()
value = newValue
}
}
})
}
observer(obj)
function $set(data, key, value) {
defineReactive(data, key, value)
}
obj.push(123, 55)
console.log(obj) //[1, 2, 3, 123, 55]
- 方法3:Proxy 实现
js
function render() {
console.log('模拟视图的更新')
}
let obj = {
name: '前端工匠',
age: { age: 100 },
arr: [1, 2, 3]
}
let handler = {
get(target, key) {
// 如果取的值是对象就在对这个对象进行数据劫持
if (typeof target[key] == 'object' && target[key] !== null) {
return new Proxy(target[key], handler)
}
return Reflect.get(target, key)
},
set(target, key, value) {
if (key === 'length') return true
render()
return Reflect.set(target, key, value)
}
}
let proxy = new Proxy(obj, handler)
proxy.age.name = '浪里行舟' // 支持新增属性
console.log(proxy.age.name) // 模拟视图的更新 浪里行舟
proxy.arr[0] = '浪里行舟' //支持数组的内容发生变化
console.log(proxy.arr) // 模拟视图的更新 ['浪里行舟', 2, 3 ]
proxy.arr.length-- // 无效
Vue 常见指令
- v-bind
- v-model
- v-on
- v-if | v-else-if | v-else
- v-for
- v-show
- v-pre
- v-clock
- v-once
- v-text
- v-html
v-if 和 v-show 的区别
- v-if 有更高的切换开销,v-show 有更高的初始渲染开销
- v-if 适合运营条件不大可能改变;v-show 适合频繁切换
- v-if 通过动态向DOM树增删DOM元素,v-show 设置display来进行隐藏
- v-if 切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show 只是简单的基于 CSS 切换
输入 URL 到页面展示的过程
- 输入地址
- DNS 解析域名
- 建立 TCP/IP 连接
- 发起请求
- 返回响应
- 解析 HTML 构建 DOM树;解析 CSS 构成样式树
- 生成渲染树并绘制
定义 CSS 的三种方式
- 内联样式
- 嵌套样式
- 外联样式
Get 和 POST 的区别
GET | POST | |
---|---|---|
后退按钮/刷新 | 无害 | 数据会被重新提交 |
书签 | 可收藏为书签 | 不可收藏为书签 |
缓存 | 可能会被缓存 | 不能缓存 |
编码类型 | application/x-www-form-urlencoded | application/x-www-form-urlencode 或 multipart/form-data |
历史 | 参数保留再浏览器历史中 | 参数不会被保留在浏览器历史中 |
数据长度限制 | URL最大长度为2048字符 | 无限制 |
数据类型限制 | 只允许 ASII 字符 | 无限制 |
安全性 | 较差,发送的数据是 URL 的一部分 | 相对安全,参数不会被保存在日志中 |
可见性 | 数据在 URL 中对所有人都可见 | 不会显示在 URL 中 |
跨域问题和解决方案
跨域问题是由于浏览器的同源策略导致的。同源策略是指,浏览器只允许同一域名下的网页进行数据交互。如果网页的协议、域名或端口号有一个与目标网页不同,则被认为是跨域请求。由于这种限制,不同域名之间的网页无法直接进行数据交互,从而产生了跨域问题
- JSONP:JSONP是一种利用动态脚本标签(script标签)实现跨域的技术。它通过在客户端动态插入一个script标签,将请求发送到不同的域名下。由于浏览器会将请求的数据嵌入到script标签中执行,从而绕过了浏览器的同源策略限制。但是,JSONP只支持GET请求,并且安全性较低
- CORS:CORS(Cross-Origin Resource Sharing)是一种基于浏览器的跨域资源共享标准。通过在服务器端设置适当的HTTP响应头信息,允许浏览器向不同域名下的网页发送跨域请求。CORS提供了一种标准化的方式来实现跨域资源共享,支持各种类型的请求(如GET、POST等),并且安全性较高
- 代理:使用代理服务器可以解决跨域问题。无论是正向代理还是反向代理,都可以将请求转发到目标服务器上,从而避免了跨域问题。但是,使用代理服务器需要配置服务器端和客户端的设置,并且需要考虑安全性、性能等方面的问题
- 正向代理:正向代理是一个位于客户端和服务器之间的代理服务器。当客户端发出请求时,请求首先会发送到代理服务器,然后由代理服务器转发给目标服务器。代理服务器会缓存目标服务器的响应,并将其返回给客户端。通过正向代理,客户端可以间接地访问目标服务器上的资源,从而避免了跨域问题。但是,使用正向代理需要配置代理服务器,并在客户端进行相应的设置
- 反向代理:反向代理与正向代理相反,它是将请求从客户端转发到目标服务器,并将目标服务器的响应返回给客户端。通过配置反向代理服务器,我们可以将客户端的请求转发到目标服务器上,并且可以实现对请求的缓存、负载均衡等功能。与正向代理不同,反向代理不需要在客户端进行任何设置,只需要配置好反向代理服务器即可
什么是 XSS 攻击
XSS 全称是 Cross Site Scripting 即跨站脚本,当目标网站目标用户浏览器渲染HTML文档的过程中,出现了不被预期的脚本指令并执行时,XSS 就发生了
作为一种 HTML 注入攻击,XSS 攻击的核心思想就是在 HTML 页面中注入恶意代码,而XSS 采用的注入方式是非常巧妙的。在 XSS 攻击中,一般有三个角色参与:攻击者、目标服务器、受害者的浏览器
由于有的服务器并没有对用户的输入进行安全方面的验证,攻击者就可以很容易地通过正常的输入手段,夹带进一些恶意的 HTML 脚本代码。当受害者的浏览器访问目标服务器上被注入恶意脚本的页面后,由于它对目标服务器的信任,这段恶意脚本的执行不会受到什么阻碍。而此时,攻击者的目的就已经达到了
如何理解 Promise
在 JavaScript 中,异步编程是一个重要的概念,它允许我们执行一些可能需要花费一些时间的操作(例如网络请求或读取大文件),而不阻塞程序的执行。Promise 是 JavaScript 中用于处理异步操作的对象。通过 Promise,我们可以将异步代码组织得更加清晰,并且更容易处理异步操作的结果
Promise 是一个代表异步操作最终完成或失败的对象。它解决了回调地狱的问题,并提供了更好的错误处理机制。一个 Promise 对象有以下三种状态:
- Pending(待定): 初始状态,既不是成功,也不是失败
- Fulfilled(已实现): 表示成功完成
- Rejected(已拒绝): 表示失败
一旦 Promise 对象的状态变为已实现或已拒绝,它将不会再改变。
React 和 Vue 的区别
- vue 提供了一系列的 api, 而 react 的 api 很少
- vue 的思想是响应式的,也就是基于是数据可变的,实现了数据的双向绑定,react 整体是函数式的思想,是单向数据流,推崇结合 immutable 来实现数据不可变
- vue 采用了 template, react采用了 jsx (本质上都是模版)
- react 依赖 Virtual DOM,而 Vue.js 使用的是 DOM 模板
- react 采用的 Virtual DOM 会对渲染出来的结果做脏检查。
- vue 在模板中提供了指令,过滤器等,可以非常方便,快捷地操作 DOM
参考文档
Vue的响应式数据与双向绑定:原理与实现解析
深入浅出Vue响应式原理(完整版)
v-if和v-show的区别详解
GET和POST请求的区别(超详细)
web前端面试 - 面试官系列
深入理解JavaScript Promise
vue和react的区别以及优劣势是什么?
web攻防之XSS攻击详解------XSS简介与类型
跨域及解决方案:正反向代理区别详解
从输入URL到页面展示的详细过程
txt
新人发文,礼貌求关❤️