12k 11 分钟

转自

https://juejin.cn/post/7163932925955112996

# 前言

最近在公司开发了一个可视化大屏,开发定制化大屏,大家可能都一个感受,开发大屏主要是两方面的工作:

  • 大屏之关键-前期的自适应适配
  • 根据 ui 稿绘制图表,调细节

而解决了适配问题后,后面就只是一个慢工出细活,耗时间的事情了。

# 适配方案分析

看了网上的各种方案,目前大家采用的大概有 3 种👇

方案实现方式优点缺点
vm vh1. 按照设计稿的尺寸,将 px 按比例计算转为 vwvh1. 可以动态计算图表的宽高,字体等,灵活性较高 2. 当屏幕比例跟 ui 稿不一致时,不会出现两边留白情况1. 每个图表都需要单独做字体、间距、位移的适配,比较麻烦
scale1. 通过 scale 属性,根据屏幕大小,对图表进行整体的等比缩放1. 代码量少,适配简单 2. 一次处理后不需要在各个图表中再去单独适配1. 因为是根据 ui 稿等比缩放,当大屏跟 ui 稿的比例不一样时,会出现周边留白情况 2. 当缩放比例过大时候,字体会有一点点模糊,就一点点 3. 当缩放比例过大时候,事件热区会偏移。
rem + vm vh1. 获得 rem 的基准值 2. 动态的计算 html根元素的font-size 3. 图表中通过 vm vh 动态计算字体、间距、位移等1. 布局的自适应代码量少,适配简单1. 因为是根据 ui 稿等比缩放,当大屏跟 ui 稿的比例不一样时,会出现周边留白情况 2. 图表需要单个做字体、间距、位移的适配

11k 10 分钟

# 文章目录

  • 序言
  • 服务端渲染的优点和缺点
  • 客户端渲染的优点和缺点
  • 服务端渲染是产生并发吗
  • 服务端渲染用户每次请求都需要重新渲染吗
  • 为什么服务端渲染只做首屏?
  • 什么情况下,可能需要进行更多的服务端渲染或客户端渲染
  • 前端渲染和前后端分离是不是一回事呢?
  • 服务端渲染模板,前端如何热更新?
  • 前后端分离,前端渲染每个页面都要去请求后端用户现在的登录状态是否有效吗?
  • 客户端渲染和服务端渲染,单页面应用和多页面应用,前端路由和服务端路由有什么区别联系?

8.3k 8 分钟

# reflect 的 13 个方法

方法参数说明
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。

3.8k 3 分钟

# 前言

今天在写代码时,用了箭头函数,出现了如下问题:

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 指向问题,这是因为不了解箭头函数属性导致的。

  • 箭头函数没有单独的 thisargumentssuper ,并且不能作为构造函数。

9.4k 9 分钟

# 前言

就目前而言,前端框架基本上被 Vue 和 React 瓜分得差不多了。如果你去面试一个前端岗位,那么或多或少都会问你一些关于 Vue 和 React 框架得知识,无论是原理还是使用,我们都有必要去了解一番。

数据响应式可以说是这些框架的一大特色与核心,这里我们就拿 Vue 来说。在 Vue2.x 时代,实现数据响应式主要是使用 Object.defineProperty() 这个 API 来实现的,而到了 Vue3.x 时代,数据响应式主要是使用 Proxy() 来实现的。

如果你还不了解 Proxy,那么你很有必要跟着本篇文章学习一下!

1.2k 1 分钟

在 JavaScript 中,使用 new 关键字来创建类的实例时,这个过程本身与时序(即在 DOM 加载之前还是之后)关系不大,而是更多地与 JavaScript 代码的执行顺序有关。然而,当你想要在创建类的实例之后进行 DOM 操作时,你需要确保 DOM 元素已经被加载和解析。

2.6k 2 分钟

首先说一下常识:

网页可见区域宽: 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;

2.6k 2 分钟

# 1. 以复制方式实现的继承

# 1.1 浅拷贝

基本类型的复制

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 对象,结果两者是指向同一个对象内存的,继承出来的子对象的属性是同一个,显然是不能满足需求的,(基本类型之间画等号是值的复制,引用类型之间画等号是引用的复制)所以就需要另谋出路。

3.1k 3 分钟

# [[Prototype]] 与 prototype

[[Prototype]] 与 prototype 是不同的:

# 凡是被两层方括号括起来的属性都是内部属性,内部属性不能通过 “对象。属性” 的方式获取。

[[Prototype]] 就是内部属性,它不能通过 “对象.[[Prototype]]” 的方式获取,但可以通过 “对象.proto” 的方式获取。

prototype 是一般属性,可以直接通过 “对象.prototype” 的方式获取。