首页 > web前端 > js教程 > 关于 JavaScript 你可能不知道的六件事

关于 JavaScript 你可能不知道的六件事

Mary-Kate Olsen
发布: 2024-10-22 06:18:03
原创
515 人浏览过

作者:刘易斯·西安奇✏️

那么,您是一名 JavaScript 开发人员?很高兴听到——你认为这段代码会返回什么?是的,这是一个棘手的问题:

function returnSomething()
{
  return
    {
      name: 'JavaScript Expert'
      contactMethod: 'Shine batsign at sky'
    }
}
登录后复制
登录后复制
登录后复制
登录后复制

在几乎任何其他语言中——C#、Java,这样的例子不胜枚举——我们可以使用 JavaScript Expert 取回对象。如果您认为在 JavaScript 中我们会得到相同的结果,这是情有可原的。

不过,请幽默一下,并将其弹出到您的开发控制台中,然后执行该函数。几乎令人难以置信的是,它返回未定义。

当事情没有按计划进行时

作为软件开发人员工作意味着您要对应用程序的工作方式负责,无论它运行得好还是不好。其中的一个主要限制是您决定使用的工具。如果您了解自己正在使用什么,那么您有望在设计软件时做出正确的选择。

JavaScript 是独一无二的,因为它是许多新软件开发人员选择的语言。想编写移动应用程序吗?只需使用 React Native 和 JavaScript。桌面应用程序? React Native 和 JavaScript。在某个地方运行的云函数? Node.js,你猜对了,还有 JavaScript。

然而,由于 JavaScript 已经存在了很长一段时间,它也有不少的问题和陷阱。其中一些问题的范围从轻微有趣到我的代码不起作用且我不知道为什么严重。

而且,即使我们生活在 Internet Explorer 6 全盛时期,尝试修复其中一些设计决策也为时已晚,因为我们会破坏太多的网络。如果当时情况确实如此,想象一下我们今天是否尝试过! ??

那么,JavaScript 为何没有按照我们预期的方式工作呢?我们来看看吧。

自动分号注入 (ASI)

开头列出的示例被 JavaScript 解释器接受,但没有产生预期的结果。原因是自动分号注入。

某些语言(例如 C#)教条地规定以分号结束每一行。 JavaScript 也使用分号来表示行尾,但分号实际上是可选的。可选的,这意味着 JavaScript 将应用一组复杂的规则来确定分号是否应该出现在那里。

在一开始的示例中,由于左括号与回车符不在同一行,因此 ASI 会在其中弹出一个。所以,就 JavaScript 而言,我们的代码实际上是这样的:

function returnSomething()
{
  return ; // <-- semicolon inserted by ASI, remainder of function not evaluated.
    {
      name: 'JavaScript Expert'
      contactMethod: 'Shine batsign at sky'
    }
}
登录后复制
登录后复制
登录后复制
登录后复制

避免这种情况的方法是将左括号与回车符放在同一行。而且,虽然分号在 JavaScript 中在技术上是可选的,但从长远来看,使用这个概念会给你带来伤害。

如果你有一个面试,你必须写JS,并且你基于“但它们是可选的”的理由而没有分号地写它,那么将会有很多文件拖沓和咯咯笑。只是不要这样做。

具有非顺序键的数组

假设我们有一个简单的数组:

function returnSomething()
{
  return
    {
      name: 'JavaScript Expert'
      contactMethod: 'Shine batsign at sky'
    }
}
登录后复制
登录后复制
登录后复制
登录后复制

我们知道我们可以对数组进行弹出、推送、追加等操作。但我们也知道,JavaScript 与其他语言一样,允许我们通过索引访问数组元素。

然而,JavaScript 的不寻常之处在于,当数组还没有达到该索引时,您还可以通过数组索引设置元素:

function returnSomething()
{
  return ; // <-- semicolon inserted by ASI, remainder of function not evaluated.
    {
      name: 'JavaScript Expert'
      contactMethod: 'Shine batsign at sky'
    }
}
登录后复制
登录后复制
登录后复制
登录后复制

不过,我有一个很好的问题要问你——当你只设置三个元素时,数组的长度是多少?可能不直观,它是 101。一方面,数组项 2 到 99 未定义是合理的,但另一方面,我们只设置了三个对象,而不是 100。

为什么重要? ​​
也许你的眼睛会从你的头上翻出来,你会说“好吧,刘易斯,你正在手动将项目分配到一个数组中,然后看着轮子脱落;这让你感到奇怪,而不是 JavaScript”。

我会理解这个立场。但想象一下,您正在嵌套的 for 循环中执行某些操作,并且选择了错误的迭代器或进行了无效计算。

在某些时候,“为什么我得到预期结果,预期结果,未定义,预期结果”的思维过程将变得疯狂,很快就会流泪!您几乎不知道您的阵列会神奇地增长以适应您想要做的事情。

唯一的问题是,你试图做错误的事情。

与 C# 等其他语言相比(没有特殊原因),数组是固定长度的。创建数组时,必须定义长度。即使对于其他动态集合对象(例如 List),您也不能分配到未定义的索引中。因此,如果您的嵌套循环尝试写入先前未分配的索引,您的程序将抛出异​​常。

例外并不好,但这可能是正确的做法。我的意思是,你是否打算创建一个瑞士奶酪阵列?有人打算这样做吗?但愿不会。  

Six things you may not know about JavaScript 如果开发商来自瑞士,那么它只是瑞士奶酪阵列。否则,这只是闪闪发光的糟糕编程。

向基元添加属性将被忽略

我们知道在 JavaScript 中我们可以将新函数分配给原型。所以,我们可以赋予字符串或数组✨特殊的力量✨。当然,这样做是糟糕的做法,因为这意味着我们的字符串原型的行为将与其他字符串原型不同,这已经给许多开发人员带来了难以言喻的心痛。

所以,我们可以这样做:

function returnSomething()
{
  return
    {
      name: 'JavaScript Expert'
      contactMethod: 'Shine batsign at sky'
    }
}
登录后复制
登录后复制
登录后复制
登录后复制

然后我们可以创建一个字符串对象:

function returnSomething()
{
  return ; // <-- semicolon inserted by ASI, remainder of function not evaluated.
    {
      name: 'JavaScript Expert'
      contactMethod: 'Shine batsign at sky'
    }
}
登录后复制
登录后复制
登录后复制
登录后复制

并且它会返回 false。

很可爱的是,我们总是可以将我们的函数随机地塞入工厂定义的字符串如何操作的实现中。

当然,所有这些好人都竭尽全力,花费了数万个小时在 TC39 规范中定义 JavaScript,但不要因此而阻止您按照自己认为合适的方式修改随机函数。

如果我们对那种特定的痛苦不满意,我们也可以根据需要随机地将新函数分配给复杂的对象,确保我们的代码将是一种非常特殊的无意义形式,只有你自己和上帝才能理解:
Six things you may not know about JavaScript
像这样组合我们的对象自然是一个糟糕的主意,但是当我们致力于这种背叛时,JavaScript 就满足了我们的要求。我们的 testObject 承担了我们投入其中的新功能。

然而,善意却以一种令人惊讶的方式耗尽了对象原语:
Six things you may not know about JavaScript
解释器承认我们尝试将函数分配给字符串基元。它甚至将这个函数回显给我们。但是,当我们尝试调用它时,我们得到一个 TypeError:testString.onlyFalse 不是一个函数。如果不可能做到这一点,通常您会期望它在赋值时抛出,而不是在函数调用时抛出。

为什么重要? ​​
无论好坏,JavaScript 都是一种高度灵活和动态的语言。这种灵活性使我们能够编写其他语言无法实现的功能。如果某些事情不起作用,那么我们应该期待一个例外。 JavaScript 接受这个尴尬的命令并表示“呃,好吧”,然后忘记它改变了这个基本期望。

类型强制

在其他强类型语言中,我们必须先定义要存储的数据的类型,然后才能存储数据。 JavaScript 没有这种同样的限制,它会很乐意将对象从其定义的类型中推开,试图让它们很好地协同工作。

一方面,它让我们不必将变量来回转换为各自的类型。所以很方便:Six things you may not know about JavaScript
布尔值也是如此:
Six things you may not know about JavaScript
这种方法是完全理智和有效的,直到我们想要参与被称为“加法”的禁忌仪式。当我们尝试将“1”和 1 加在一起时,会发生什么?类型强制是怎样进行的?
Six things you may not know about JavaScript
当我们把 bool 带到聚会上时,疯狂欢闹会成倍增加:
Six things you may not know about JavaScript
哦——是因为 bool 在某种程度上是一个数字吗?
Six things you may not know about JavaScript不。这是一个布尔值。由于某些原因,JavaScript 正在剃掉正方形的讨厌边缘,以将其装入圆孔中。

为什么重要? ​​
当你做一些像将数字相加这样的基本事情时,结果不同可能会产生一些奇怪的错误。这是一个很好的提醒,在进行比较时要坚持使用三等号 (===),因为在类型之间切换可能不会给您预期的结果。

功能吊装

对于我们今天使用的语言,一个重要的方面是所谓的“函数提升”。本质上,这意味着您可以将函数写入文件中的任意位置,并且可以在声明函数之前调用它们:

function returnSomething()
{
  return
    {
      name: 'JavaScript Expert'
      contactMethod: 'Shine batsign at sky'
    }
}
登录后复制
登录后复制
登录后复制
登录后复制

这很方便,因为我们不必手动重新排序代码即可使其工作。

但是,描述函数的方法不止一种。在此示例中,我们使用函数声明来执行此操作。我们还可以使用函数表达式:

function returnSomething()
{
  return ; // <-- semicolon inserted by ASI, remainder of function not evaluated.
    {
      name: 'JavaScript Expert'
      contactMethod: 'Shine batsign at sky'
    }
}
登录后复制
登录后复制
登录后复制
登录后复制

为什么重要? ​​
在这两种情况下声明函数之间没有很大的区别,但如果你选择了错误的函数,你将无法调用你的函数,除非你在声明它之后调用它。

空是一个对象

在其他语言中,对象属性可以被赋值,也可以为空。 null 表示该属性未分配。在我们的头脑中很容易等同——那里要么有一个对象,要么它是空的。如果我们愿意,我们还可以将属性分配回 null。

JavaScript 通过使用 null 和未定义来使这种情况变得复杂。但都是一样的,对吧?你要么手里有球,要么没有。

毫不奇怪,并不完全相同。在 JavaScript 中,null 表示有意缺少值,而 undefined 表示隐含缺少值。所以,无论是故意的、明确的,还是天上写的,事实就是没有价值=没有价值,对吧?

不幸的是,这又不是等式的计算方式。

那么,undefined 是什么类型?
Six things you may not know about JavaScript

好的,那么 null 的类型是什么?
Six things you may not know about JavaScript

?它是一个物体。所以在 JavaScript 中,复杂对象和 null 的类型是相同的——它们都是对象:
Six things you may not know about JavaScript

为什么重要? ​​
JavaScript 没有内置强大的类型检查系统,并且只有少数基本类型可供选择。因此,使用 typeof 来理解变量中的内容可能会变得很棘手。如果我们的变量保存一个有效的对象,那么我们就会得到对象。但如果它为空,我们仍然会得到对象。认为空引用是一个对象是违反直觉的。

结论

毫无疑问,JavaScript 作为一种语言如今非常受欢迎。随着时间的推移,npm 等其他生态系统继续托管大量软件包,JavaScript 只会继续流行。

但是事情已经过去了。无论 null 是一个对象有多么奇怪,或者 JavaScript 会在它认为合适的地方弹出分号,这些系统可能永远不会被弃用、更改或删除。有趣的是,我想说,如果自动分号注入在一夜之间关闭,它可能会导致比 CrowdStrike 更新更大的全球中断。

当然,更改其中一项会对网络造成严重破坏。实际上,让开发人员意识到这些特定的语言怪癖比实际返回并解决原始问题更安全,也可能更实用。

所以,去做正确的选择,别忘了使用分号!


LogRocket:通过了解上下文更轻松地调试 JavaScript 错误

调试代码始终是一项乏味的任务。但你越了解自己的错误,就越容易纠正它们。

LogRocket 允许您以新的、独特的方式理解这些错误。我们的前端监控解决方案跟踪用户与 JavaScript 前端的互动,使您能够准确查看用户的操作导致了错误。

Six things you may not know about JavaScript

LogRocket 记录控制台日志、页面加载时间、堆栈跟踪、带有标头正文的慢速网络请求/响应、浏览器元数据和自定义日志。了解 JavaScript 代码的影响从未如此简单!

免费试用。

以上是关于 JavaScript 你可能不知道的六件事的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板