被难倒了! 针对高级前端的八个级JavaScript面试问题

2023-11-13

JavaScript 是一种功能强大的语言,也是构建现代 Web 的基础之一。这种强大的语言也有一些自己的怪癖。例如,你知道 0 === -0 会计算为 true,或者 Number("") 会返回 0 吗?

有时候,这些怪癖会让你百思不得其解,甚至让你怀疑 Brendan Eich 在发明 JavaScript 的那一天是不是状态不佳。但这里的重点并不是说 JavaScript 是一种糟糕的编程语言,或者如其批评者所说的那样,是一种“邪恶”的语言。所有的编程语言都有某种程度的怪癖,JavaScript 也不例外。

在这篇博客文章中,我们将深入解释一些重要的 JavaScript 面试问题。我的目标是彻底解释这些面试问题,以便我们能够理解背后的基本概念,并希望在面试中解决其他类似的问题。

1、仔细观察 + 和 - 运算符

console.log(1 + '1' - 1);

你能猜到在上面这种情况下,JavaScript 的 + 和 - 运算符会有什么行为吗?

当 JavaScript 遇到 1 + '1' 时,它会使用 + 运算符来处理这个表达式。+ 运算符有一个有趣的特性,那就是当其中一个操作数是字符串时,它更倾向于执行字符串的连接。在我们的例子中,'1' 是一个字符串,因此 JavaScript 隐式地将数字 1 转换为字符串。因此,1 + '1' 变成了 '1' + '1',结果是字符串 '11'。

现在,我们的等式是 '11' - 1。- 运算符的行为正好相反。它更倾向于执行数字减法,而不考虑操作数的类型。当操作数不是数字类型时,JavaScript 会执行隐式转换,将它们转换为数字。在这种情况下,'11' 被转换为数字值 11,表达式简化为 11 - 1。

综合考虑:

'11' - 1 = 11 - 1 = 10

2、数组元素的复制

考虑以下的 JavaScript 代码,并尝试找出其中的问题:

function duplicate(array) {
  for (var i = 0; i < array.length; i++) {
    array.push(array[i]);
  }
  return array;
}

const arr = [1, 2, 3];
const newArr = duplicate(arr);
console.log(newArr);

在这段代码片段中,我们需要创建一个新数组,该数组包含输入数组的重复元素。初步检查后,代码似乎通过复制原始数组 arr 中的每个元素来创建一个新数组 newArr。然而,在 duplicate 函数内部出现了一个严重的问题。

duplicate 函数使用循环来遍历给定数组中的每个项目。但在循环内部,它使用 push() 方法在数组末尾添加新元素。这导致数组每次都会变长,从而产生一个问题:循环永远不会停止。因为数组长度不断增加,循环条件(i < array.length)始终为真。这使得循环无限进行下去,导致程序陷入僵局。

为了解决由于数组长度增长而导致的无限循环问题,可以在进入循环之前将数组的初始长度存储在一个变量中。然后,可以使用这个初始长度作为循环迭代的限制。这样,循环只会针对数组中的原始元素进行,并不会受到由于添加重复项而导致数组增长的影响。以下是修改后的代码:

function duplicate(array) {
  var initialLength = array.length; // 存储初始长度
  for (var i = 0; i < initialLength; i++) {
    array.push(array[i]); // 推入每个元素的副本
  }
  return array;
}

const arr = [1, 2, 3];
const newArr = duplicate(arr);
console.log(newArr);

输出将显示数组末尾的重复元素,并且循环不会导致无限循环:

[1, 2, 3, 1, 2, 3]

3、prototype 和 proto 的区别

prototype 属性是与 JavaScript 中的构造函数相关联的属性。构造函数用于在 JavaScript 中创建对象。当您定义一个构造函数时,还可以将属性和方法附加到其 prototype 属性上。这些属性和方法然后变得可以被该构造函数创建的所有对象实例访问。因此,prototype 属性充当共享方法和属性的通用存储库。

考虑以下代码片段:

// 构造函数
function Person(name) {
  this.name = name;
}

// 添加一个方法到 prototype
Person.prototype.sayHello = function() {
  console.log(`Hello, my name is ${this.name}.`);
};

// 创建实例
const person1 = new Person("Haider Wain");
const person2 = new Person("Omer Asif");

// 调用共享的方法
person1.sayHello();  // 输出:Hello, my name is Haider Wain.
person2.sayHello();  // 输出:Hello, my name is Omer Asif.

另一方面,__proto__ 属性,通常读作 "dunder proto",存在于每一个 JavaScript 对象中。在 JavaScript 中,除了原始类型外,一切都可以被视为对象。每个这样的对象都有一个原型,该原型作为对另一个对象的引用。__proto__ 属性简单地是对这个原型对象的引用。

当你试图访问对象上的一个属性或方法时,JavaScript 会进行查找过程来找到它。这个过程主要涉及两个步骤:

对象的自有属性:JavaScript 首先检查对象自身是否直接拥有所需的属性或方法。如果在对象内找到了该属性,则直接访问和使用。原型链查找:如果在对象自身没有找到该属性,JavaScript 将查看对象的原型(由 __proto__ 属性引用)并在那里搜索该属性。这个过程会递归地沿着原型链进行,直到找到该属性或直到查找达到 Object.prototype。如果在 Object.prototype 中甚至没有找到该属性,JavaScript 将返回 undefined,表示该属性不存在。

4、作用域

当编写 JavaScript 代码时,理解作用域的概念非常重要。作用域指的是变量在代码的不同部分的可访问性或可见性。下面我们通过一个代码片段来更仔细地了解这个概念:

function foo() {
  console.log(a);
}

function bar() {
  var a = 3;
  foo();
}

var a = 5;
bar();

代码定义了两个函数 foo() 和 bar(),以及一个值为5的变量 a。所有这些声明都发生在全局作用域中。在bar()函数内部,声明了一个变量a并赋值为 3。那么当bar()函数被调用时,你认为会输出哪个值的a?

当JavaScript引擎执行这段代码时,全局变量a被声明并赋值为5。然后调用了bar()函数。在bar()函数内部,声明了一个局部变量a并赋值为3。这个局部变量a与全局变量a是不同的。之后,从bar()函数内部调用了foo()函数。

在foo()函数内部,console.log(a)语句试图输出变量a的值。由于在foo()函数的作用域内没有定义局部变量a,JavaScript会查找作用域链以找到最近的名为a的变量。

现在,我们来解答JavaScript将在哪里搜索变量a的问题。它会查找bar函数的作用域吗,还是会探索全局作用域?事实证明,JavaScript会在全局作用域中搜索,这种行为是由一个叫做词法作用域的概念驱动的。

词法作用域是指函数或变量在代码中被编写时的作用域。当我们定义了foo函数,它被赋予了访问自己的局部作用域和全局作用域的权限。这一特性在我们无论在哪里调用foo函数时都是一致的,无论是在bar函数内部还是在其他模块中运行。词法作用域并不是由我们在哪里调用函数来决定的。

最终结果是,输出始终是全局作用域中找到的a的值,在这个例子中是5。

然而,如果我们在bar函数内部定义了foo函数,情况就会有所不同:

function bar() {
  var a = 3;

  function foo() {
    console.log(a);
  }

  foo();
}

var a = 5;
bar();

在这种情况下,foo 的词法作用域将包括三个不同的作用域:它自己的局部作用域,bar 函数的作用域,以及全局作用域。词法作用域是由你在源代码中放置代码的位置在编译时决定的。

当这段代码运行时,foo 位于 bar 函数内部。这种安排改变了作用域的动态。现在,当foo试图访问变量a时,它首先会在自己的局部作用域内进行搜索。由于没有找到a,它会扩大搜索范围到bar函数的作用域。果然,那里存在一个值为3的a。因此,控制台语句将输出3。

5、对象强制类型转换

const obj = {
  valueOf: () => 42,
  toString: () => 27
};
console.log(obj + '');

一个引人入胜的方面是探究JavaScript如何处理对象转换为基本值,例如字符串、数字或布尔值。这是一个有趣的问题,测试你是否了解对象的强制类型转换。

在像字符串连接或算术运算这样的场景中与对象一起工作时,这种转换至关重要。为了实现这一点,JavaScript 依赖两个特殊的方法:valueOf 和 toString。

valueOf 方法是JavaScript对象转换机制的一个基础部分。当一个对象在需要基本值的上下文中被使用时,JavaScript 首先会在对象内部查找valueOf方法。在valueOf方法不存在或不返回适当的基本值的情况下,JavaScript会退回到toString方法。这个方法负责提供对象的字符串表示形式。

回到我们最初的代码片段:

const obj = {
  valueOf: () => 42,
  toString: () => 27
};

console.log(obj + '');

当我们运行这段代码时,对象obj被转换为一个基本值。在这种情况下,valueOf 方法返回42,然后由于与空字符串的连接,它被隐式地转换为字符串。因此,代码的输出将是 42。

然而,在valueOf方法不存在或不返回适当的基本值的情况下,JavaScript会退回到toString方法。让我们修改之前的示例:

const obj = {
  toString: () => 27
};

console.log(obj + '');

在这里,我们已经移除了 valueOf 方法,只留下了返回数字27的toString方法。在这种情况下,JavaScript 将依赖 toString 方法进行对象转换。

6、理解对象键(Object Keys)

当在JavaScript中使用对象时,理解键是如何在其他对象的上下文中被处理和分配的非常重要。考虑以下代码片段,并花点时间猜测输出:

let a = {};
let b = { key: 'test' };
let c = { key: 'test' };

a[b] = '123';
a[c] = '456';

console.log(a);

乍一看,这段代码似乎应该生成一个具有两个不同键值对的对象a。然而,由于JavaScript对对象键的处理方式,结果完全不同。

JavaScript 使用默认的toString()方法将对象键转换为字符串。为什么呢?在JavaScript中,对象键总是字符串(或 symbols),或者通过隐式强制转换自动转换为字符串。当你在对象中使用除字符串之外的任何值(例如,数字、对象或符号)作为键时,JavaScript将在使用它作为键之前内部将该值转换为其字符串表示形式。

因此,当我们在对象a中使用对象b和c作为键时,两者都转换为相同的字符串表示形式:[object Object]。由于这种行为,第二个赋值a[c] = '456';会覆盖第一个赋值a[b] = '123';。

最终,当我们记录对象a时,我们观察到以下输出:

{ '[object Object]': '456' }

7、双等号运算符

console.log([] == ![]);

这个有点复杂。那么,你认为输出会是什么呢?

这个问题相当复杂。那么,你认为输出结果会是什么呢?让我们一步一步地来评估。首先,让我们看一下两个操作数的类型:

typeof([]) // "object"
typeof(![]) // "boolean"

对于 [],它是一个对象,这是可以理解的,因为在JavaScript中,包括数组和函数在内的一切都是对象。但操作数 ![] 是如何具有布尔类型的呢?让我们尝试理解一下。当你使用 ! 与一个原始值(primitive value)一起时,会发生以下转换:

  • Falsy Values(假值):如果原始值是一个假值(例如 false、0、null、undefined、NaN 或一个空字符串 ''),应用 ! 将把它转换为 true。
  • Truthy Values(真值):如果原始值是一个真值(即任何不是假值的值),应用 ! 将把它转换为 false。

在我们的案例中,[] 是一个空数组,这在JavaScript中是一个真值。因为 [] 是真值,![] 变成了 false。因此,我们的表达式变为:

[] == ![]
[] == false

现在,让我们继续了解 == 运算符。当使用 == 运算符比较两个值时,JavaScript会执行“抽象相等性比较算法(Abstract Equality Comparison Algorithm)”。这个算法会考虑比较值的类型并进行必要的转换。

在我们的情况中,让我们把 x 记作 [],y 记作 ![]。我们检查了 x 和 y 的类型,并发现 x 是对象,y 是布尔值。由于 y 是布尔值,x 是对象,算法的第7个条件被应用:

如果 Type(y) 是 Boolean,则返回 x == ToNumber(y) 的比较结果。

这意味着如果其中一个类型是布尔值,我们需要在比较之前将其转换为数字。ToNumber(y) 的值是多少呢?如我们所见,[] 是一个真值,取反使其变为 false。因此,Number(false) 是 0。

[] == false
[] == Number(false)
[] == 0

现在我们有了 [] == 0 的比较,这次算法的第8个条件起作用:

如果 Type(x) 是 String 或 Number,而 Type(y) 是 Object,则返回 x == ToPrimitive(y) 的比较结果。

基于这个条件,如果其中一个操作数是对象,我们必须将其转换为一个原始值。这就是“ToPrimitive算法”出现的地方。我们需要将 x(即 [])转换为一个原始值。数组在JavaScript中是对象。当将对象转换为原始值时,valueOf 和 toString 方法会起作用。在这种情况下,valueOf 返回数组本身,这不是一个有效的原始值。因此,我们转向 toString 以获取输出。将 toString 方法应用于空数组会得到一个空字符串,这是一个有效的原始值:

[] == 0
[].toString() == 0
"" == 0

将空数组转换为字符串给了我们一个空字符串 "",现在我们面对的比较是:"" == 0。

现在其中一个操作数的类型是字符串,另一个是数字,算法的第5个条件成立:

如果 Type(x) 是 String,而 Type(y) 是 Number,则返回 ToNumber(x) == y 的比较结果。

因此,我们需要将空字符串 "" 转换为数字,这给了我们一个 0。

"" == 0
ToNumber("") == 0
0 == 0

最后,两个操作数具有相同的类型和条件1成立。由于两者具有相同的值,最终的输出是:

0 == 0 // true

至此,我们已经利用了强制转换(coercion)来解决了我们探讨的最后几个问题,这是掌握JavaScript和解决面试中这类常见问题的重要概念。我强烈建议你查看我的关于强制转换的详细博客文章。它以清晰和彻底的方式解释了这个概念。这里是链接。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

被难倒了! 针对高级前端的八个级JavaScript面试问题 的相关文章

  • 使用 WMI 查找服务的依赖关系,然后区分依赖的服务和依赖的驱动程序

    MSDN 上有一个代码示例 它使用 WMI 枚举特定服务的所有依赖项 http msdn microsoft com en us library aa393673 v vs 85 aspx http msdn microsoft com e
  • JavaScript 对象引用缓存

    我们的代码库中有很多对象 它们的名称空间是为了避免冲突 Example App local view MyView 在我在代码库中看到的大多数地方 我们使用完整路径来获取对对象的引用 并且这在同一函数中重复多次 Example functi
  • 在javascript中使用“return !0”有什么意义吗?

    如果您转到谷歌结果页面并运行rwt toString 你会看到这个函数的返回调用是 return 0 我想不出任何理由为什么这不会总是如此true 这只是一个简写吗true 还是还有更多事情发生 总是如此 但下载需要 2 个字节 0是 2
  • 如何使用 LinkedIn javascript sdk 检索包括所有字段的职位列表?

    我想要获取 LinkedIn 会员在其个人资料中输入的每个职位的 ID 头衔 摘要 开始日期 结束日期 当前状态和公司名称 我测试了一个查询休息控制台 https apigee com console linkedin我得到了想要的结果 查
  • 如何根据按钮单击折叠和展开 Kendo UI 树视图中的所有树节点?

    这是行不通的 您可以使用此代码 1 崩溃 折叠kendoTree查看文档 http docs kendoui com api web treeview methods collapse treeview kendoTreeView var
  • 如何使用 axios / jest 测试失败的请求

    我创建了一个非常小的应用程序 如果您传递硬币和数量 它可以计算为某些加密货币支付的总价格 我想测试错误 但我总是收到 收到的承诺已解决而不是被拒绝 我相信这是因为如果 url 错误 axios 仍然会解决承诺 我遇到的第二个问题是 我尝试测
  • Google 饼图未显示所有数据行

    我正在尝试绘制人口与国家名称的关系图 我发现 Google 可视化库仅渲染前几个 实际上数字似乎是随机的 具体取决于我使用的数据 有时添加 其他 条目 但它没有t 实际上具有其余条目的值 Example 1 With all countri
  • 来自 DataURL 的 Blob?

    Using FileReader s readAsDataURL 我可以将任意数据转换为数据 URL 有没有办法将数据 URL 转换回Blob使用内置浏览器 API 的实例 用户 Matt 一年前提出了以下代码 如何在javascript中
  • 如何获取 RxJSSubject 或 Observable 的当前值?

    我有 Angular 2 服务 import Storage from storage import Injectable from angular2 core import Subject from rxjs Subject Inject
  • 如何从表中选择所有偶数 id?

    我想从 MySQL 数据库的表中选择所有甚至帖子 ID 然后显示它们 我还想获取所有带有奇怪 id 的帖子并将它们显示在其他地方 我想使用 PHP 来完成此操作 因为这是我使用的服务器端语言 或者 我是否必须选择所有帖子 然后使用 Java
  • 在 asp.net vb 中通过第一个下拉列表值填充第二个下拉列表

    我在使用 asp net vb 时遇到了一些问题 我想做的是有2个下拉框 第一个下拉菜单将有 1 2 3 例如 第二个下拉菜单将有 A 乙 C 默认情况下 但是 如果选择 1 我希望第二个下拉菜单自动选择 c 我不知道 JavaScript
  • 具有行组的 JQuery 斑马条纹表

    我通常将斑马条纹表行设置为奇数 偶数 如下所示 效果很好 table tbody tr visible even this addClass even table tbody tr visible odd this addClass odd
  • 引入 V8 后,Google Apps 脚本无法为其他用户完全执行

    我编写了一个脚本 得到了这里好心人的大力帮助 该脚本使用 Google Sheets 脚本复制 Google Drive 上的文件夹 和内容 它运行了很长一段时间 但后来我启用了 V8 引擎 现在已禁用 问题是 它仍然适用于我 也许还有其他
  • 使用 jQuery 仅从字符串末尾修剪空格

    我知道 jQuery trim 函数 但我需要的是一种仅从字符串末尾修剪空格的方法 而不是开头 So str this is a string 会成为 str this is a string 有什么建议么 Thanks 您可以使用正则表达
  • Javascript 选择 onchange='this.form.submit()'

    我有一个带有选择和一些文本输入的表单 我希望在更改选择时提交表单 使用以下方法可以正常工作 onchange this form submit 但是 如果表单还包含提交按钮 则当选择更改时 表单不会提交 我猜有某种冲突 我在这里有什么选择
  • 有没有办法防止输入 type=“number” 获得多个点值?

    我只想得到十进制值 如 1 5 0 56 等 但它允许多个点 有什么办法可以预防吗 您可以使用pattern属性
  • 如何在 JavaScript 中获取浮点数的小数位?

    我想要的是与 Number prototype toPrecision 几乎相反的 这意味着当我有数字时 它有多少位小数 例如 12 3456 getDecimals 4 对于任何想知道如何更快地完成此操作 无需转换为字符串 的人 这里有一
  • 使用 jquery 提供附加功能时菜单未正确对齐

    I need to make a mega menu similar to one as show in image below 到目前为止 我已经能够在某种程度上使其发挥作用 例如jsFiddle 在这里 http jsfiddle ne
  • Serviceworker Bug event.respondWith

    我的 serviceworker 的逻辑是 当发生获取事件时 它首先获取包含一些布尔值 而不是 event request url 的端点 并根据我正在调用的值检查该值event respondWith 对于当前的获取事件 我正在提供来自缓
  • 使用 Lodash 将对象键转换为具有键值数量的数组[重复]

    这个问题在这里已经有答案了 我有一个产品对象 products bread 1 milk 2 cheese 2 chicken 1 我想要一个包含产品名称的数组 如下所示 products bread milk milk cheese ch

随机推荐

  • 本征正交分解(POD)入门(详解)

    思来想去还是把题目从 简介 改成了 入门 详解 其实详解主要就是针对可能没接触过矩阵论的同学 我也是研一才学的 入门是指的我会解释一些名词 方便理解 另外PCA 主成分分析 本质上就是POD 只是我最近翻的热工学论文大部分都用的POD这个名
  • 楠姐技术漫话:接着唠唠社区发现

    halo 大家好很开心又和大家见面了 在第一篇 楠姐技术漫画 图计算的那些事 发布之后 楠姐收到了很多建议 鼓励和支持 非常感谢大家的喜欢 所以楠姐尽自己所能马不停蹄开始第二篇的创作 虽迟但到 本篇依然是风控算法分享 其实也依然算是图算法系
  • 从零开始搭建物联网平台(四)EMQ-X消息中间件

    物联网的消息中间件有很多 如ActiveMq RabbitMq Emq 以及自己实现的netty borker 这里为什么要选择EMQ呢 首先 在使用emqx之前我用过ActiveMq由于是国外开发的 对国内产品的支持不够好 文档和社区也远
  • c++ 使用libcurl下载网络图像

    include
  • 解决ERROR: This script does not work on Python 2.7 The minimum supported Python version is 3.7

    前言 最近因项目需要 部署区块链的网络时候 需要一个问题 运行下载的install sh脚本时候 提示出错 然后找到该脚本文件 找到对应报错的语句 发现是python的pip没有下载好的缘故 解决 问题原因知道了 然后就下载一个Pip就好
  • 家政服务小程序制作:提升生活质量、解决烦恼

    在现代快节奏的生活中 家政服务扮演着越来越重要的角色 借助家政服务小程序的制作 为用户提供便捷可靠的家务帮助已成为一种新的选择 那么家政服务小程序的制作过程是怎么样的呢 带来的好处有哪些呢 1 家政服务小程序的定义与优势 小程序是微信里面的
  • 第十八讲:神州三层交换机DHCP中继服务的配置

    当DHCP客户机和DHCP服务器不在同一个网段时 由DHCP中继传递DHCP报文 增加DHCP中继功能的好处是不必为每个网段都设置DHCP服务器 同一个DHCP服务器可以为很多个子网的客户机提供网络配置参数 即节约了成本又方便了管理 这就是
  • 流水灯实验过程

    流水灯 1 基本思路 先让P1口全为高电平 灯不亮 通过为左移 位右移动来实现依次点亮LED灯一个具有注脚的文本 1 用for循环语句嵌套 写程序 include
  • 在SpringBoot中整合其它技术

    在SpringBoot中整合其它技术 前言 一 SpringBoot整合SpringMVC 1 修改web端口 2 访问静态资源 3 添加拦截器 4 更详细的日志 二 SpringBoot整合MyBatis 1 整合连接池 2 整合myba
  • 老板说,可以在家办公,顿时办公室沸腾了……

    在美国的IT行业中 在家办公 WFH 仍然不是普遍现象 这有点匪夷所思 因为 1 员工渴望在家办公 2 有些雇主已经提供在家办公 3 反对在家办公的意见不能成立 在家办公 并不意味着 100 在家工作 从不需要去办公室 而是公司应该提供这些
  • opencv进行简单的裂缝检测

    师弟最近要使用四旋翼进行桥梁探伤 主要是用运动相机搭载在四轴上检测裂缝 就顺便搞了一下有关于裂缝检测的图像处理 算法比较简单 没有考虑太多复杂情况 在简单墙面背景下基本可以找到裂缝并框定 基本思路为 先转换彩色图为灰度图 然后进行自适应局部
  • 区块链能解决媒体行业哪些问题?

    对于最近炙手可热的区块链技术 最近流行起这样一句笑言 没有什么问题是人工智能解决不了的 如果有 那就用区块链解决 这句话虽然略显夸张 但也反映出人们对于区块链技术的高度期待 区块链有三个显著的特点 去中心化 可追溯 不可篡改 这三个特点为它
  • Linux 中不适用功能键切换TTY

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 本简要指南介绍了在类 Unix 操作系统中如何在不使用功能键的情况下切换 TTY 在进一步讨论之前 我们将了解 TTY 是什么 正如在 AskUbuntu 论坛的一个答案
  • C#中关于在一个数据库同时修改2个数据的语法使用!

    SqlCommand cmd new SqlCommand update Student set Sname updateName where Sno Sno con SqlCommand cmd2 new SqlCommand updat
  • AES对称加密工具类(GCM)

    import java io UnsupportedEncodingException import java security InvalidAlgorithmParameterException import java security
  • Java实现图片格式转换(通过ImageIO)

    文章目录 粗略介绍ImageIO 一 遍历文件夹 二 转换图片格式 视频效果演示 粗略介绍ImageIO ImageIO是javax imageio包下的一个类 用于实现Java中关于图片输入输出的一种类 这个类中所有方法均为静态方法 因此
  • 2.9 UiPath中断活动Continue的介绍和使用

    Continue的介绍 跳过当前For Each 循环内的迭代 结束本次循环 Continue控件只能用于For Each 循环中 Continue在UiPath中结合For Each循环的使用 打开设计器 在设计库中新建一个Flowcha
  • ODrive踩坑(四)AS5047P-SPI绝对值磁编码器,不需每次上电校准无刷电机,直接上电可用

    前几篇介绍了ODrive在Windows下的使用环境搭建 以及TLE5012B AS5047P的ABI配置 ODrive教程资源导航 ODrive踩坑 一 windows下使用环境的搭建 odrivetool及USB驱动的安装 ODrive
  • 软件版本比较之——Java算法实现软件版本比较

    最近遇到一个开发中的小问题 软件版本比较 例如2 12 3和2 2 1这两个版本号 哪个更新 其实 客户端版本检测更新 检测后台是否有更新版本可更新 Java中最简单的一种方法便是获取当前客户端版本号 与服务端提供的最新版本号做equals
  • 被难倒了! 针对高级前端的八个级JavaScript面试问题

    JavaScript 是一种功能强大的语言 也是构建现代 Web 的基础之一 这种强大的语言也有一些自己的怪癖 例如 你知道 0 0 会计算为 true 或者 Number 会返回 0 吗 有时候 这些怪癖会让你百思不得其解 甚至让你怀疑