前端服务端渲染和客户端渲染
# 文章目录
- 序言
- 服务端渲染的优点和缺点
- 客户端渲染的优点和缺点
- 服务端渲染是产生并发吗
- 服务端渲染用户每次请求都需要重新渲染吗
- 为什么服务端渲染只做首屏?
- 什么情况下,可能需要进行更多的服务端渲染或客户端渲染
- 前端渲染和前后端分离是不是一回事呢?
- 服务端渲染模板,前端如何热更新?
- 前后端分离,前端渲染每个页面都要去请求后端用户现在的登录状态是否有效吗?
- 客户端渲染和服务端渲染,单页面应用和多页面应用,前端路由和服务端路由有什么区别联系?
| 方法 | 参数说明 |
|---|---|
| Reflect.get(target, name, receiver) | target: 目标对象。 |
| name: 是我们要读取的属性。 | |
| receiver (可选): 可以理解为上下文 this 对象。 | |
| Reflect.set(target,name,value,receiver) | target: 我们需要操作的对象。 |
| name: 我们需要设置该对象的属性名。 | |
| value: 我们要设置的属性值。 | |
| receiver: 可以理解为上下文 this 对象。如果我们在设置值的时候遇到 setter 函数,该参数就指向与 setter 中上下文 this 对象。 | |
| Reflect.apply(target,thisArg,args) | target: 我们的目标函数。 |
| thisArg: target 函数调用的时候绑定的 this 对象。 | |
| args: 就是函数参数列表。 | |
| Reflect.construct(target,args[, newTarget]) | target: 被运行的目标函数。 |
| args: 调用构造函数传递的参数数组或伪数组。 | |
| newTarget: 也是构造函数,表示使用 Reflect.construct 后生成的实列对象是谁的实列。如果没有该参数,默认生成的实列对象就和 target 构造函数是一样的。 | |
| Reflect.defineProperty(target,name,desc) | 该方法 Object.defineProperty 方法类似的,不过唯一的区别是 Reflect.defineProperty 返回值是一个 Boolean 的值。 |
| Reflect.deleteProperty(target,name) | target: 表示要操作的对象。 |
| name: 表示要删除该对象上的属性。 | |
| Reflect.has(target,name) | target: 就是改对象。 |
| name 的含义是:该对象上的属性。 | |
| Reflect.ownKeys(target) | target:它是一个对象。 |
| Reflect.preventExtensions(target) | target:必须是一个对象,否则的话会抛出一个异常。 |
| Reflect.isExtensible(target) | target:表示目标对象。 |
| Reflect.getOwnPropertyDescriptor(target, name) | target: 表示的是目标对象。 |
| name: 表示目标对象的属性 该方法的具体含义是:如果目标对象中的属性描述符存在的话,就返回这个属性描述符,如果不存在,就返回 undefined。 | |
| Reflect.getPrototypeOf(target) | 该方法是返回一个对象的原型的,也就是说内部的 [[Prototype]] 属性的值。 |
| Reflect.setPrototypeOf(target, prototype) | 方法的作用是设置一个对象的原型。如果设置成功的话,这个对象就返回一个 true,如果设置失败的话,这个对象就返回一个 false。 |
今天在写代码时,用了箭头函数,出现了如下问题:
function Drawing(shape) { | |
this.shape = shape | |
} | |
Drawing.prototype.drawShape = (radius, x, y) => { //bug 问题所在 | |
return this.shape.draw(radius, x, y) //this 指向了全局 | |
} |
报错信息:
Error in created hook: "TypeError: Cannot read properties of undefined (reading 'shape')"
然后,改成 function 后,错误消除。
function Drawing(shape) { | |
this.shape = shape | |
} | |
Drawing.prototype.drawShape = function(radius, x, y) { | |
return this.shape.draw(radius, x, y) | |
} |
原因是 this 指向问题,这是因为不了解箭头函数属性导致的。
this 、 arguments 、 super ,并且不能作为构造函数。就目前而言,前端框架基本上被 Vue 和 React 瓜分得差不多了。如果你去面试一个前端岗位,那么或多或少都会问你一些关于 Vue 和 React 框架得知识,无论是原理还是使用,我们都有必要去了解一番。
数据响应式可以说是这些框架的一大特色与核心,这里我们就拿 Vue 来说。在 Vue2.x 时代,实现数据响应式主要是使用
Object.defineProperty()这个 API 来实现的,而到了 Vue3.x 时代,数据响应式主要是使用Proxy()来实现的。如果你还不了解 Proxy,那么你很有必要跟着本篇文章学习一下!
在 JavaScript 中,使用 new 关键字来创建类的实例时,这个过程本身与时序(即在 DOM 加载之前还是之后)关系不大,而是更多地与 JavaScript 代码的执行顺序有关。然而,当你想要在创建类的实例之后进行 DOM 操作时,你需要确保 DOM 元素已经被加载和解析。
首先说一下常识:
网页可见区域宽: document.body.clientWidth; | |
网页可见区域高: document.body.clientHeight; | |
网页可见区域宽: document.body.offsetWidth (包括边线的宽); | |
网页可见区域高: document.body.offsetHeight (包括边线的宽); | |
网页正文全文宽: document.body.scrollWidth; | |
网页正文全文高: document.body.scrollHeight; | |
网页被卷去的高: document.body.scrollTop; | |
网页被卷去的左: document.body.scrollLeft; | |
网页正文部分上: window.screenTop; | |
网页正文部分左: window.screenLeft; | |
屏幕分辨率的高: window.screen.height; | |
屏幕分辨率的宽: window.screen.width; | |
屏幕可用工作区高度: window.screen.availHeight; | |
屏幕可用工作区宽度:window.screen.availWidth; |
[[Prototype]] 与 prototype 是不同的:
[[Prototype]] 就是内部属性,它不能通过 “对象.[[Prototype]]” 的方式获取,但可以通过 “对象.proto” 的方式获取。
prototype 是一般属性,可以直接通过 “对象.prototype” 的方式获取。
基本类型的复制
var parent = { | |
lanage: "chinese" | |
} | |
var child = { | |
name: "xxx", | |
age: 12 | |
} | |
function extend(parent, child) { | |
var child = child || {}; | |
for (const propertype in parent) { | |
child[propertype] = parent[propertype]; | |
} | |
} | |
extend(parent, child); | |
console.log(child);//{ name: 'xxx', age: 12, lanage: 'chinese' } |
以上代码中,通过一个 extend () 函数,将父对象 parent 的属性遍历赋给子对象 child,从而实现继承。
但是这种字面量复制的方式存在巨大的缺陷,当父对象有引用类型的属性时,通过这么复制的方式,就像上一节中的 var b = a 一样,只会将 a 对象的引用赋给 b 对象,结果两者是指向同一个对象内存的,继承出来的子对象的属性是同一个,显然是不能满足需求的,(基本类型之间画等号是值的复制,引用类型之间画等号是引用的复制)所以就需要另谋出路。
Browser 对象中有一个 Navigator 对象,这个对象中包含所有浏览器的信息

其中,一些常用设备访问时返回的 userAgent 属性如下:
| 访问设备 | 返回 userAgent 属性值 |
|---|---|
| Win10 电脑 | Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 Edg/91.0.864.37 |
| iphone 手机 | Mozilla/5.0 (iPhone; CPU iPhone OS 14_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1 Mobile/15E148 Safari/604.1 |
| 安卓手机 | Mozilla/5.0 (Linux; Android 9; PAR-AL00; HMSCore 5.3.0.312; GMSCore 19.6.29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.93 HuaweiBrowser/11.1.1.300 Mobile Safari/537.36 |
| ipad 平板 | Mozilla/5.0 (iPad; CPU OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1 |