【Javascript基础】--零基础--超详细且简洁的Javascript笔记--代码质量(03)

news2024/11/16 8:32:53

在浏览器中调试

在编写代码前看看调试。

调试是指在一个脚本中找出并修复错误的过程。

在这里我们将会使用 Chrome(谷歌浏览器),因为它拥有足够多的功能,其他大部分浏览器的功能也与之类似。

“资源(Sources)”面板

你的 Chrome 版本可能看起来有一点不同,但是它应该还是处于很明显的位置。

  • 在 Chrome 中打开一个页面。
  • 使用快捷键 F12 打开开发者工具。
  • 选择 Sources(资源) 面板。

如果你是第一次这么做,那你应该会看到下面这个样子:
在这里插入图片描述

切换按钮会打开文件列表的选项卡。

资源(Sources)面板包含三个部分:

  1. 文件导航(File Navigator) 区域列出了 HTML、JavaScript、CSS 和包括图片在内的其他依附于此页面的文件。Chrome 扩展程序也会显示在这。
  2. 代码编辑(Code Editor) 区域展示源码。
  3. JavaScript 调试(JavaScript Debugging) 区域是用于调试的,我们很快就会来探索它。

现在你可以再次点击切换按钮 隐藏资源列表来给代码腾出一些空间。

控制台(Console)

如果我们按下 Esc,下面会出现一个控制台,我们可以输入一些命令然后按下 Enter 来执行。

语句执行完毕之后,其执行结果会显示在下面。

例如,1+2 将会返回 3,而 hello("debugger") 函数调用什么也没返回,所以结果是 undefined
在这里插入图片描述

断点(Breakpoints)

断点 是调试器会自动暂停 JavaScript 执行的地方。

当代码被暂停时,我们可以检查当前的变量,在控制台执行命令等等。换句话说,我们可以调试它。

我们总是可以在右侧的面板中找到断点的列表。当我们在数个文件中有许多断点时,这是非常有用的。它允许我们:

  • 快速跳转至代码中的断点(通过点击右侧面板中的对应的断点)。
  • 通过取消选中断点来临时禁用对应的断点。
  • 通过右键单击并选择移除来删除一个断点。
  • ……等等。

条件断点

在行号上 右键单击 允许你创建一个 条件 断点。只有当给定的表达式(你创建条件断点时提供的表达式)为真时才会被触发。

当我们需要在特定的变量值或参数的情况下暂停程序执行时,这种调试方法就很有用了。

“debugger” 命令

我们也可以使用 debugger 命令来暂停代码,像这样:

function hello(name) {
  let phrase = `Hello, ${name}!`;

  debugger;  // <-- 调试器会在这停止

  say(phrase);
}

这样的命令只有在开发者工具打开时才有效,否则浏览器会忽略它。

暂停并查看

请打开右侧的信息下拉列表(箭头指示出的地方)。这里允许你查看当前的代码状态:

  1. 察看(Watch) —— 显示任意表达式的当前值。

    你可以点击加号 + 然后输入一个表达式。调试器将显示它的值,并在执行过程中自动重新计算该表达式。

  2. 调用栈(Call Stack) —— 显示嵌套的调用链。

    此时,调试器正在 hello() 的调用链中,被 index.html 中的一个脚本调用(这里没有函数,因此显示 “anonymous”)

    如果你点击了一个堆栈项,调试器将跳到对应的代码处,并且还可以查看其所有变量。

  3. 作用域(Scope) —— 显示当前的变量。

    Local 显示当前函数中的变量,你还可以在源代码中看到它们的值高亮显示了出来。

    Global 显示全局变量(不在任何函数中)。

    这里还有一个 this 关键字,目前我们还没有学到它,不过我们很快就会学习它了。

跟踪执行

现在是 跟踪 脚本的时候了。

在右侧面板的顶部是一些关于跟踪脚本的按钮。让我们来使用它们吧。
在这里插入图片描述

  • “恢复(Resume)”:继续执行,快捷键 F8。

继续执行。如果没有其他的断点,那么程序就会继续执行,并且调试器不会再控制程序。

  • “下一步(Step)”:运行下一条(即当前行)指令,快捷键 F9。

    运行下一条语句。

    一次接一次地点击此按钮,整个脚本的所有语句会被逐个执行。

  • “跨步(Step over)”:运行下一条(即当前行)指令,但 不会进入到一个函数中,快捷键 F10。

    跟上一条命令“下一步(Step)”类似,但如果下一条语句是函数调用则表现不同。这里的函数指的是:不是内建的如 alert 函数等,而是我们自己写的函数。

    如果我们对比一下,“下一步(Step)”命令会进入嵌套函数调用并在其第一行暂停执行,而“跨步(Step over)”对我们不可见地执行嵌套函数调用,跳过了函数内部。执行会在该函数调用后立即暂停。

    如果我们对该函数的内部执行不感兴趣,这命令会很有用。

  • “步入(Step into)”,快捷键 F11。

    和“下一步(Step)”类似,但在异步函数调用情况下表现不同。

    至于之后,只需要记住“下一步(Step)”命令会忽略异步行为,例如 setTimeout(计划的函数调用),它会过一段时间再执行。而“步入(Step into)”会进入到代码中并等待(如果需要)。

  • “步出(Step out)”:继续执行到当前函数的末尾,快捷键 Shift+F11。

    继续执行当前函数内的剩余代码,并暂停在调用当前函数的下一行代码处。当我们使用 偶然地进入到一个嵌套调用,但是我们又对这个函数不感兴趣时,我们想要尽可能的继续执行到最后的时候是非常方便的。

  • 启用/禁用所有的断点。

    这个按钮不会影响程序的执行。只是一个批量操作断点的开/关。

  • 启用/禁用出现错误时自动暂停脚本执行。

    当启动此功能,如果开发者工具是打开着的时候,任何脚本执行错误都会导致该脚本执行自动暂停。然后我们可以在调试器中分析变量来看一下什么出错了。因此如果我们的脚本因为错误挂掉的时候,我们可以打开调试器,启用这个选项然后重载页面,查看一下哪里导致它挂掉了和当时的上下文是什么。

Continue to here

在代码中的某一行上右键,在显示的关联菜单(context menu)中点击一个非常有用的名为 “Continue to here” 的选项。

当你想要向前移动很多步到某一行为止,但是又懒得设置一个断点时非常的方便。

日志记录

想要输出一些东西到控制台上?console.log 函数可以满足你。

例如:将从 04 的值输出到控制台上:

// 打开控制台来查看
for (let i = 0; i < 5; i++) {
  console.log("value", i);
}

普通用户看不到这个输出,它是在控制台里面的。要想看到它 —— 要么打开开发者工具中的 Console(控制台)选项卡,要么在一个其他的选项卡中按下 Esc:这会在下方打开一个控制台。

如果我们在代码中有足够的日志记录,那么我们可以从记录中看到刚刚发生了什么,而不需要借助调试器。

小结

我们可以看到,这里有 3 种方式来暂停一个脚本:

  1. 断点。
  2. debugger 语句。
  3. error(如果开发者工具是打开状态,并且按钮 是开启的状态)。

当脚本执行暂停时,我们就可以进行调试:检查变量,跟踪代码来查看执行出错的位置。

代码风格

我们的代码必须尽可能的清晰和易读。

语法

下面是一个备忘单,其中列出了一些建议的规则:
在这里插入图片描述

下面详细讨论一下这些规则和它们的原因吧。

注意:这些所谓风格只是推荐写法,你可以有自己喜欢的方式去书写漂亮的代码

花括号

在大多数的 JavaScript 项目中,花括号以 “Egyptian” 风格书写

左花括号与相应的关键词在同一行上

而不是新起一行。左括号前还应该有一个空格,如下所示:

if (condition) {
  // do this
  // ...and that
  // ...and that
}

单行构造(如 if (condition) doSomething())也是一个重要的用例。我们是否应该使用花括号?如果是,那么在哪里?

下面是这几种情况的注释,你可以自己判断一下它们的可读性:

  1. 😠 初学者常这样写。非常不好!这里不需要花括号:

    if (n < 0) {alert(`Power ${n} is not supported`);}
    
  2. 😠 拆分为单独的行,不带花括号。永远不要这样做,添加新行很容易出错:

    if (n < 0)
      alert(`Power ${n} is not supported`);
    
  3. 😏 写成一行,不带花括号 —— 如果短的话,也是可以的:

    if (n < 0) alert(`Power ${n} is not supported`);
    
  4. 😃 最好的方式:

    if (n < 0) {
      alert(`Power ${n} is not supported`);
    }
    

对于很短的代码,写成一行是可以接受的:例如 if (cond) return null。但是代码块(最后一个示例)通常更具可读性。

行的长度

没有人喜欢读一长串代码,最好将代码分割一下。

例如:

// 回勾引号 ` 允许将字符串拆分为多行
let str = `
  ECMA International's TC39 is a group of JavaScript developers,
  implementers, academics, and more, collaborating with the community
  to maintain and evolve the definition of JavaScript.
`;

对于 if 语句:

if (
  id === 123 &&
  moonPhase === 'Waning Gibbous' &&
  zodiacSign === 'Libra'
) {
  letTheSorceryBegin();
}

一行代码的最大长度应该在团队层面上达成一致。通常是 80 或 120 个字符。

缩进

有两种类型的缩进:

  • 水平方向上的缩进:2 或 4 个空格。

    一个水平缩进通常由 2 或 4 个空格或者 “Tab” 制表符(Tab 键)构成。

    选择空格而不是 tabs 的优点之一是,这允许你做出比 “Tab” 制表符更加灵活的缩进配置。

    例如,我们可以将参数与左括号对齐,像下面这样:

    show(parameters,
         aligned, // 左边有 5 个空格
         one,
         after,
         another
      ) {
      // ...
    }
    
  • 垂直方向上的缩进:用于将代码拆分成逻辑块的空行。

    即使是单个函数通常也被分割为数个逻辑块。在下面的示例中,初始化的变量、主循环结构和返回值都被垂直分割了:

    function pow(x, n) {
      let result = 1;
      //              <--
      for (let i = 0; i < n; i++) {
        result *= x;
      }
      //              <--
      return result;
    }
    

    插入一个额外的空行有助于使代码更具可读性。写代码时,不应该出现连续超过 9 行都没有被垂直分割的代码。

分号

每一个语句后面都应该有一个分号。即使它可以被跳过。

在 JavaScript 中,极少数情况下,换行符有时不会被解释为分号,这时代码就容易出错。

嵌套的层级

尽量避免代码嵌套层级过深。

例如,在循环中,有时候使用 continue 指令以避免额外的嵌套是一个好主意。

例如,不应该像下面这样添加嵌套的 if 条件:

for (let i = 0; i < 10; i++) {
  if (cond) {
    ... // <- 又一层嵌套
  }
}

我们可以这样写:

for (let i = 0; i < 10; i++) {
  if (!cond) continue;
  ...  // <- 没有额外的嵌套
}

使用 if/elsereturn 也可以做类似的事情。

例如,下面的两个结构是相同的。

第一个:

function pow(x, n) {
  if (n < 0) {
    alert("Negative 'n' not supported");
  } else {
    let result = 1;

    for (let i = 0; i < n; i++) {
      result *= x;
    }

    return result;
  }
}

第二个:

function pow(x, n) {
  if (n < 0) {
    alert("Negative 'n' not supported");
    return;
  }

  let result = 1;

  for (let i = 0; i < n; i++) {
    result *= x;
  }

  return result;
}

但是第二个更具可读性,因为 n < 0 这个“特殊情况”在一开始就被处理了。一旦条件通过检查,代码执行就可以进入到“主”代码流,而不需要额外的嵌套。

函数位置

如果你正在写几个“辅助”函数和一些使用它们的代码,那么有三种方式来组织这些函数。

  1. 在调用这些函数的代码的 上方 声明这些函数:

    // 函数声明
    function createElement() {
      ...
    }
    
    function setHandler(elem) {
      ...
    }
    
    function walkAround() {
      ...
    }
    
    // 调用函数的代码
    let elem = createElement();
    setHandler(elem);
    walkAround();
    
  2. 先写调用代码,再写函数

    // 调用函数的代码
    let elem = createElement();
    setHandler(elem);
    walkAround();
    
    // --- 辅助函数 ---
    function createElement() {
      ...
    }
    
    function setHandler(elem) {
      ...
    }
    
    function walkAround() {
      ...
    }
    
  3. 混合:在第一次使用一个函数时,对该函数进行声明。

大多数情况下,第二种方式更好。

这是因为阅读代码时,我们首先想要知道的是“它做了什么”。如果代码先行,那么在整个程序的最开始就展示出了这些信息。之后,可能我们就不需要阅读这些函数了,尤其是它们的名字清晰地展示出了它们的功能的时候。

自动检查器

检查器是可以自动检查代码样式,并提出改进建议的工具。

它们的妙处在于进行代码风格检查时,还可以发现一些代码错误,例如变量或函数名中的错别字。因此,即使你不想坚持某一种特定的代码风格,我也建议你安装一个检查器。

我使用的是 ESLint

大多数检查器都可以与编辑器集成在一起:只需在编辑器中启用插件并配置代码风格即可。

例如,要使用 ESLint 你应该这样做:

  1. 安装 Node.JS。
  2. 使用 npm install -g eslint 命令(npm 是一个 JavaScript 包安装工具)安装 ESLint。
  3. 在你的 JavaScript 项目的根目录(包含该项目的所有文件的那个文件夹)创建一个名为 .eslintrc 的配置文件。
  4. 在集成了 ESLint 的编辑器中安装/启用插件。大多数编辑器都有这个选项。

下面是一个 .eslintrc 文件的例子:

{
  "extends": "eslint:recommended",
  "env": {
    "browser": true,
    "node": true,
    "es6": true
  },
  "rules": {
    "no-console": 0,
    "indent": 2
  }
}

这里的 "extends" 指令表示我们是基于 “eslint:recommended” 的设置项而进行设置的。之后,我们制定我们自己的规则。

此外,某些 IDE 有内建的检查器,这非常方便,但是不像 ESLint 那样可自定义。

注释

正如我们在代码结构所了解到的那样,注释可以是以 // 开始的单行注释,也可以是 /* ... */ 结构的多行注释。

我们通常通过注释来描述代码怎样工作和为什么这样工作。

糟糕的注释

新手倾向于使用注释来解释“代码中发生了什么”。就像这样:

// 这里的代码会先做这件事(……)然后做那件事(……)
// ……谁知道还有什么……
very;
complex;
code;

但在好的代码中,这种“解释性”注释的数量应该是最少的。严格地说,就算没有它们,代码也应该很容易理解。

关于这一点有一个很棒的原则:“如果代码不够清晰以至于需要一个注释,那么或许它应该被重写。”

配方:分解函数

有时候,用一个函数来代替一个代码片段是更好的,就像这样:

function showPrimes(n) {
  nextPrime:
  for (let i = 2; i < n; i++) {

    // 检测 i 是否是一个质数(素数)
    for (let j = 2; j < i; j++) {
      if (i % j == 0) continue nextPrime;
    }

    alert(i);
  }
}

更好的变体,使用一个分解出来的函数 isPrime

function showPrimes(n) {

  for (let i = 2; i < n; i++) {
    if (!isPrime(i)) continue;

    alert(i);
  }
}

function isPrime(n) {
  for (let i = 2; i < n; i++) {
    if (n % i == 0) return false;
  }

  return true;
}

现在我们可以很容易地理解代码了。函数自己就变成了一个注释。这种代码被称为 自描述型 代码。

配方:创建函数

如果我们有一个像下面这样很长的代码块:

// 在这里我们添加威士忌(译注:国外的一种酒)
for(let i = 0; i < 10; i++) {
  let drop = getWhiskey();
  smell(drop);
  add(drop, glass);
}

// 在这里我们添加果汁
for(let t = 0; t < 3; t++) {
  let tomato = getTomato();
  examine(tomato);
  let juice = press(tomato);
  add(juice, glass);
}

// ...

我们像下面这样,将上面的代码重构为函数,可能会是一个更好的变体:

addWhiskey(glass);
addJuice(glass);

function addWhiskey(container) {
  for(let i = 0; i < 10; i++) {
    let drop = getWhiskey();
    //...
  }
}

function addJuice(container) {
  for(let t = 0; t < 3; t++) {
    let tomato = getTomato();
    //...
  }
}

同样,函数本身就可以告诉我们发生了什么。没有什么地方需要注释。并且分割之后代码的结构也更好了。每一个函数做什么、需要什么和返回什么都非常地清晰。

实际上,我们不能完全避免“解释型”注释。例如在一些复杂的算法中,会有一些出于优化的目的而做的一些巧妙的“调整”。但是通常情况下,我们应该尽可能地保持代码的简单和“自我描述”性。

好的注释

所以,解释性注释通常来说都是不好的。那么哪一种注释才是好的呢?

  • 描述架构

    对组件进行高层次的整体概括,它们如何相互作用、各种情况下的控制流程是什么样的……简而言之 —— 代码的鸟瞰图。

  • 记录函数的参数和用法

例如:

/**
 * 返回 x 的 n 次幂的值。
 *
 * @param {number} x 要改变的值。
 * @param {number} n 幂数,必须是一个自然数。
 * @return {number} x 的 n 次幂的值。
 */
function pow(x, n) {
  ...
}

这种注释可以帮助我们理解函数的目的,并且不需要研究其内部的实现代码,就可以直接正确地使用它。

小结

一个好的开发者的标志之一就是他的注释:它们的存在甚至它们的缺席

好的注释可以使我们更好地维护代码,一段时间之后依然可以更高效地回到代码高效开发。

注释这些内容:

  • 整体架构,高层次的观点。
  • 函数的用法。
  • 重要的解决方案,特别是在不是很明显时。

Polyfill 和转译器

JavaScript 语言在稳步发展。也会定期出现一些对语言的新提议,它们会被分析讨论,如果认为有价值,就会被加入到 https://tc39.github.io/ecma262/ 的列表中,然后被加到规范中。

因此,一个 JavaScript 引擎只能实现标准中的一部分是很常见的情况。

作为程序员,我们希望使用最新的特性。好东西越多越好!

另一方面,如何让我们现代的代码在还不支持最新特性的旧引擎上工作?

有两个工作可以做到这一点:

  1. 转译器(Transpilers)。
  2. 垫片(Polyfills)。

下面一起了解它们的工作原理以及它们在 Web 开发中的位置。

转译器(Transpilers)

转译器是一种可以将源码转译成另一种源码的特殊的软件。它可以解析(“阅读和理解”)现代代码,并使用旧的语法结构对其进行重写,进而使其也可以在旧的引擎中工作。

例如,在 ES2020 之前没有“空值合并运算符” ??。所以,如果访问者使用过时了的浏览器访问我们的网页,那么该浏览器可能就不明白 height = height ?? 100 这段代码的含义。

转译器会分析我们的代码,并将 height ?? 100 重写为 (height !== undefined && height !== null) ? height : 100

// 在运行转译器之前
height = height ?? 100;

// 在运行转译器之后
height = (height !== undefined && height !== null) ? height : 100;

现在,重写了的代码适用于更旧版本的 JavaScript 引擎。

通常,开发者会在自己的计算机上运行转译器,然后将转译后的代码部署到服务器。

说到名字,Babel是最著名的转译器之一。

现代项目构建系统,例如 Webpack,提供了在每次代码更改时自动运行转译器的方法,因此很容易将代码转译集成到开发过程中。

垫片(Polyfills)

新的语言特性可能不仅包括语法结构和运算符,还可能包括内建函数。

例如,Math.trunc(n) 是一个“截断”数字小数部分的函数,例如 Math.trunc(1.23) 返回 1

在一些(非常过时的)JavaScript 引擎中没有 Math.trunc 函数,所以这样的代码会执行失败。

由于我们谈论的是新函数,而不是语法更改,因此无需在此处转译任何内容。我们只需要声明缺失的函数。

更新或添加这些新函数的JS脚本被称为“polyfill”。它“填补”了空白并添加了缺失的实现。

对于这种特殊情况,Math.trunc 的 polyfill 是一个实现它的脚本,如下所示:

if (!Math.trunc) { // 如果没有这个函数
  // 实现它
  Math.trunc = function(number) {
    // Math.ceil 和 Math.floor 甚至存在于上古年代的 JavaScript 引擎中
    // 在本教程的后续章节中会讲到它们
    return number < 0 ? Math.ceil(number) : Math.floor(number);
  };
}

JavaScript 是一种高度动态的语言。脚本可以添加或修改任何函数,甚至包括内建函数。

两个有趣的 polyfill 库:

  • core js支持了很多特性,允许只包含需要的特性。
  • polyfill.io提供带有 polyfill 的脚本的服务,具体取决于特性和用户的浏览器。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/111850.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

为什么编程入门从Python学起?

目前&#xff0c;青岛市的小学、初中、高中对于编程教育和信息学的推进几乎都选中了Python。 浙江省新高中信息技术教材改革项目中&#xff0c;高中新生开始使用新教材&#xff0c;里面的编程语言将换用 Python&#xff0c;Python 将正式纳入高考内容。 Python是一种代表简单主…

看BP(后向投影算法)英文文献生词记录

看BP&#xff08;后向投影算法&#xff09;英文文献生词记录 总的来说&#xff0c;该论文是在讲CAT和SAR的后向投影算法之间的联系与区别 acoustic imaging 原声成像 polychromatic 美 [pɒlɪkroʊ’mtɪk] 英 [pɒlɪkrəʊ’mtɪk] adj.多色的 illumination 美 [ɪˌlum…

建筑“光储直柔”配用电系统关键技术分析

低碳发展背景下的建筑“光储直柔”配用电系统关键技术分析&#xff08;2021&#xff09; 摘 要 在低碳发展的背景下&#xff0c;为适应高比例的可再生能源结构&#xff0c;建筑电气化已经成为未来的发展趋势。建筑电气化不仅要提高建筑电气化率&#xff0c;还要发展新型建筑配…

RV1126笔记九:RTMP服务器搭建

若该文为原创文章,转载请注明原文出处 一、介绍 搭建RTMP服务器主要是为了在RV1126上实现RTMP推拉流功能测试使用,如果条件允许可以把RTMP服务器部署到公网服务器上,搭建的RTMP服务器只支持h264,h265需要自行修改。 这里介绍两种方式搭建RTMP服务器: 一、使用开源的SRS…

从架构层面了解Kubernetes

一. 背景 1、 为什么K8s战胜了Swarm、Mesos 从使用上来说以声明式API来降低运维的操作成本。在生态系统建设方面以极高的可扩展性来提升社区活跃度。从这两个方面既可以填充K8s的不足&#xff0c;也极大的简化了运维操作过程。 2、 架构侧面 在K8s的各种文档、书籍中都没有…

【源码共读】Vue2 中为什么可以使用 this 访问各种选项中的属性?

如何阅读源码 网上有很多关于源码阅读的文章&#xff0c;每个人都有自己的方式&#xff0c;但是网上的文章都是精炼之后的&#xff0c;告诉你哪个文件、那个函数、那个变量是干什么的&#xff1b; 但是没有告诉你这些是怎么找到的&#xff0c;这些是怎么理解的&#xff0c;这…

港科夜闻|叶玉如校长回应「香港创科发展蓝图」

关注并星标每周阅读港科夜闻建立新视野 开启新思维1、香港科大校长叶玉如教授回应「香港创科发展蓝图」。近日&#xff0c;粤港澳大湾区院士联盟表示希望特区政府切实落实「蓝图」内容&#xff0c;设立具体行动措施和可量化的指标&#xff0c;以更大的魄力和决心实现当中的目标…

C++11标准模板(STL)- 算法(std::iota)

定义于头文件 <algorithm> 算法库提供大量用途的函数&#xff08;例如查找、排序、计数、操作&#xff09;&#xff0c;它们在元素范围上操作。注意范围定义为 [first, last) &#xff0c;其中 last 指代要查询或修改的最后元素的后一个元素。 用从起始值开始连续递增的…

10.1、Django框架入门--后台管理

文章目录预备知识MVC模式和MTV模式MVC模式MTV 模式Django框架Django框架简介Django框架中的后台管理启动后台admin站点管理数据库迁移创建管理员用户管理界面本地化创建并使用一个应用bookapp项目的数据库模型创建数据库模型生成数据库表数据库上的基本操作启用后台admin站点管…

【源码共读】如何优雅的处理 Promise 的错误

Promise解决了优雅的解决了回调地域的问题&#xff0c;现在已经大范围的使用Promise&#xff0c;但是在使用Promise的过程中&#xff0c;最令人头疼的就是错误处理的方式。 Promise 的错误处理方式 据我对Promise的了解&#xff0c;Promise的错误处理分为下面的几种方式&…

324页13万字高校数字化校园大数据中心及大数据平台建设方案

一、 数据中心总体规划 云资源中心加大数据分析与高性能主要分为计算资源、内存资源、存储资源、网络资源&#xff0c;大数据分析系统&#xff0c;高性能作业调度系统&#xff0c;本项目在充分整合XXX高校数据中心资源的基础上&#xff0c;配置必要软硬件设备&#xff0c;为XXX…

我国军靴行业现状分析:两大利好因素推动市场良好发展

根据观研报告网发布的《中国军靴市场发展趋势分析与投资前景预测报告&#xff08;2022-2029年&#xff09;》显示&#xff0c;军靴是指供军事单位在行军&#xff0c;作战时穿着的鞋靴&#xff0c;一般采用头层牛皮制作&#xff0c;具有耐用、舒适以及良好的防水透气效果特点。军…

对Python的学习【如何查看路径和安装包】

1&#xff1a;怎么查看本地电脑的Python版本号及安装路径&#xff1a; 对于Windows平台&#xff0c;打开cmd 使用命令py -0p 【其中0是零】 显示已安装的 python 版本且带路径的列表&#xff0c;参见下图&#xff1a; 其中带星号*的为默认版本。 2:怎么查看python pip…

Fragment

Fragment简单认识 1.简介 在大屏幕设备上支持更加动态和灵活的UI设计就是一种卡片的设计思路一个Activity可以有多个Fragment&#xff0c;一个Fragment可以被多个Activity使用可以进行动态的添加&#xff0c;替换和删除Fragment有着自己的生命周期&#xff0c;同时受到Activity…

python循环语句(三)

一.while 循环 条件满足无限执行 (1) 定义格式 while 条件&#xff1a;条件为True时重复执行# 写法要求与if语句类似使用示例&#xff1a; i 0 while i < 100:print("观止study")i 1 # 等效于 i i 1 # 需要设置循环终止的条件&#xff0c;如i 1配合 i <…

【Pandas入门教程】如何读取和写入表格数据

如何读取和写入表格数据 来源&#xff1a;Pandas官网&#xff1a;https://pandas.pydata.org/docs/getting_started/intro_tutorials/index.html 文章目录如何读取和写入表格数据导包【1】如何读取和写入表格数据【2】小结导包 import pandas as pd数据介绍&#xff1a; 使用存…

【信管5.2】估算活动资源与持续时间

估算活动资源与持续时间在经过上次课程的学习后&#xff0c;我们已经了解到了进度、活动的概念及定义&#xff0c;并且简单地学习了下活动顺序如何排列的一些工具技术。今天&#xff0c;我们学习的主要方向是估算活动资源与估算活动持续时间这两个过程&#xff0c;另外我们还会…

python:写你的第一个爬虫代码

什么是爬虫 爬虫spider&#xff0c;是指向网站或者网络发出请求&#xff0c;获取资源后分析并提取对自己有用的数据的程序。 request&#xff1a;是指用户将自己的信息通过浏览器发送给服务器。 response&#xff1a;服务器收到用户的请求分析后&#xff0c;返回的数据。 注意&…

【Pandas入门教程】如何选择DataFrame的子集

如何选择DataFrame的子集 来源&#xff1a;Pandas官网&#xff1a;https://pandas.pydata.org/docs/getting_started/intro_tutorials/index.html 文章目录如何选择DataFrame的子集导包数据准备【1】如何从DataFrame中选择特定列&#xff1f;【2】如何从DataFrame中筛选特定行【…