作者:刘易斯·西安奇✏️
那么,您是一名 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 ; // <p>避免这种情况的方法是将左括号与回车符放在同一行。而且,虽然分号在 JavaScript 中在技术上是可选的,但从长远来看,使用这个概念会给你带来伤害。 </p><p>如果你有一个面试,你必须写JS,并且你基于“但它们是可选的”的理由而没有分号地写它,那么将会有很多文件拖沓和咯咯笑。只是不要这样做。</p> <h2> 具有非顺序键的数组 </h2> <p>假设我们有一个简单的数组:<br> </p> <pre class="brush:php;toolbar:false">function returnSomething() { return { name: 'JavaScript Expert' contactMethod: 'Shine batsign at sky' } }
我们知道我们可以对数组进行弹出、推送、追加等操作。但我们也知道,JavaScript 与其他语言一样,允许我们通过索引访问数组元素。
然而,JavaScript 的不寻常之处在于,当数组还没有达到该索引时,您还可以通过数组索引设置元素:
function returnSomething() { return ; // <p>不过,我有一个很好的问题要问你——当你只设置三个元素时,数组的长度是多少?可能不直观,它是 101。一方面,数组项 2 到 99 未定义是合理的,但另一方面,我们只设置了三个对象,而不是 100。</p> <p><strong>为什么重要?</strong> <br> 也许你的眼睛会从你的头上翻出来,你会说“好吧,刘易斯,你正在手动将项目分配到一个数组中,然后看着轮子脱落;这让你感到奇怪,而不是 JavaScript”。 </p> <p>我会理解这个立场。但想象一下,您正在嵌套的 for 循环中执行某些操作,并且选择了错误的迭代器或进行了无效计算。 </p> <p>在某些时候,“为什么我得到预期结果,预期结果,未定义,预期结果”的思维过程将变得疯狂,很快就会流泪!您几乎不知道您的阵列会神奇地增长以适应您想要做的事情。 </p> <p>唯一的问题是,你试图做错误的事情。 </p> <p>与 C# 等其他语言相比(没有特殊原因),数组是固定长度的。创建数组时,必须定义长度。即使对于其他动态集合对象(例如 List<t>),您也不能分配到未定义的索引中。因此,如果您的嵌套循环尝试写入先前未分配的索引,您的程序将抛出异常。 </t></p> <p>例外并不好,但这可能是正确的做法。我的意思是,你是否打算创建一个瑞士奶酪阵列?有人打算这样做吗?但愿不会。 </p> <p><img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/172954908866066.jpg?x-oss-process=image/resize,p_40" class="lazy" alt="Six things you may not know about JavaScript"> <em>如果开发商来自瑞士,那么它只是瑞士奶酪阵列。否则,这只是闪闪发光的糟糕编程。</em></p> <h2> 向基元添加属性将被忽略 </h2> <p>我们知道在 JavaScript 中我们可以将新函数分配给原型。所以,我们可以赋予字符串或数组✨特殊的力量✨。当然,这样做是糟糕的做法,因为这意味着我们的字符串原型的行为将与其他字符串原型不同,这已经给许多开发人员带来了难以言喻的心痛。 </p><p>所以,我们可以这样做:<br> </p> <pre class="brush:php;toolbar:false">function returnSomething() { return { name: 'JavaScript Expert' contactMethod: 'Shine batsign at sky' } }
然后我们可以创建一个字符串对象:
function returnSomething() { return ; // <p>并且它会返回 false。 </p> <p>很可爱的是,我们总是可以将我们的函数随机地塞入工厂定义的字符串如何操作的实现中。 </p> <p>当然,所有这些好人都竭尽全力,花费了数万个小时在 TC39 规范中定义 JavaScript,但不要因此而阻止您按照自己认为合适的方式修改随机函数。 </p> <p>如果我们对那种特定的痛苦不满意,我们也可以根据需要随机地将新函数分配给复杂的对象,确保我们的代码将是一种非常特殊的无意义形式,只有你自己和上帝才能理解:<br> <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/172954908998836.jpg?x-oss-process=image/resize,p_40" class="lazy" alt="Six things you may not know about JavaScript"> <br> 像这样组合我们的对象自然是一个糟糕的主意,但是当我们致力于这种背叛时,JavaScript 就满足了我们的要求。我们的 testObject 承担了我们投入其中的新功能。 </p> <p>然而,善意却以一种令人惊讶的方式耗尽了对象原语:<br> <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/172954909074477.jpg?x-oss-process=image/resize,p_40" class="lazy" alt="Six things you may not know about JavaScript"> <br> 解释器承认我们尝试将函数分配给字符串基元。它甚至将这个函数回显给我们。但是,当我们尝试调用它时,我们得到一个 TypeError:testString.onlyFalse 不是一个函数。如果不可能做到这一点,通常您会期望它在赋值时抛出,而不是在函数调用时抛出。 </p> <p><strong>为什么重要?</strong> <br> 无论好坏,JavaScript 都是一种高度灵活和动态的语言。这种灵活性使我们能够编写其他语言无法实现的功能。如果某些事情不起作用,那么我们应该期待一个例外。 JavaScript 接受这个尴尬的命令并表示“呃,好吧”,然后忘记它改变了这个基本期望。</p> <h2> 类型强制 </h2> <p>在其他强类型语言中,我们必须先定义要存储的数据的类型,然后才能存储数据。 JavaScript 没有这种同样的限制,它会很乐意将对象从其定义的类型中推开,试图让它们很好地协同工作。 </p><p>一方面,它让我们不必将变量来回转换为各自的类型。所以很方便:<img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/172954909188290.jpg?x-oss-process=image/resize,p_40" class="lazy" alt="Six things you may not know about JavaScript"><br> 布尔值也是如此:<br> <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/172954909211047.jpg?x-oss-process=image/resize,p_40" class="lazy" alt="Six things you may not know about JavaScript"> <br> 这种方法是完全理智和有效的,直到我们想要参与被称为“加法”的禁忌仪式。当我们尝试将“1”和 1 加在一起时,会发生什么?类型强制是怎样进行的? <br> <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/172954909319865.jpg?x-oss-process=image/resize,p_40" class="lazy" alt="Six things you may not know about JavaScript"> <br> 当我们把 bool 带到聚会上时,<del>疯狂</del>欢闹会成倍增加:<br> <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/172954909445100.jpg?x-oss-process=image/resize,p_40" class="lazy" alt="Six things you may not know about JavaScript"> <br> 哦——是因为 bool 在某种程度上是一个数字吗? <br> <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/172954909562905.jpg?x-oss-process=image/resize,p_40" class="lazy" alt="Six things you may not know about JavaScript">不。这是一个布尔值。由于某些原因,JavaScript 正在剃掉正方形的讨厌边缘,以将其装入圆孔中。 </p> <p><strong>为什么重要?</strong> <br> 当你做一些像将数字相加这样的基本事情时,结果不同可能会产生一些奇怪的错误。这是一个很好的提醒,在进行比较时要坚持使用三等号 (===),因为在类型之间切换可能不会给您预期的结果。</p> <h2> 功能吊装 </h2> <p>对于我们今天使用的语言,一个重要的方面是所谓的“函数提升”。本质上,这意味着您可以将函数写入文件中的任意位置,并且可以在声明函数之前调用它们:<br> </p> <pre class="brush:php;toolbar:false">function returnSomething() { return { name: 'JavaScript Expert' contactMethod: 'Shine batsign at sky' } }
这很方便,因为我们不必手动重新排序代码即可使其工作。
但是,描述函数的方法不止一种。在此示例中,我们使用函数声明来执行此操作。我们还可以使用函数表达式:
function returnSomething() { return ; // <p><strong>为什么重要?</strong> <br> 在这两种情况下声明函数之间没有很大的区别,但如果你选择了错误的函数,你将无法调用你的函数,除非你在声明它之后调用它。</p> <h2> 空是一个对象 </h2> <p>在其他语言中,对象属性可以被赋值,也可以为空。 null 表示该属性未分配。在我们的头脑中很容易等同——那里要么有一个对象,要么它是空的。如果我们愿意,我们还可以将属性分配回 null。 </p> <p>JavaScript 通过使用 null 和未定义来使这种情况变得复杂。但都是一样的,对吧?你要么手里有球,要么没有。 </p><p>毫不奇怪,并不完全相同。在 JavaScript 中,null 表示有意缺少值,而 undefined 表示隐含缺少值。所以,无论是故意的、明确的,还是天上写的,事实就是没有价值=没有价值,对吧? </p> <p>不幸的是,这又不是等式的计算方式。 </p> <p>那么,undefined 是什么类型? <br> <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/172954909681428.jpg?x-oss-process=image/resize,p_40" class="lazy" alt="Six things you may not know about JavaScript"> </p> <p>好的,那么 null 的类型是什么? <br> <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/172954909737640.jpg?x-oss-process=image/resize,p_40" class="lazy" alt="Six things you may not know about JavaScript"> </p> <p>?它是一个物体。所以在 JavaScript 中,复杂对象和 null 的类型是相同的——它们都是对象:<br> <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/172954909893812.jpg?x-oss-process=image/resize,p_40" class="lazy" alt="Six things you may not know about JavaScript"> </p> <p><strong>为什么重要?</strong> <br> JavaScript 没有内置强大的类型检查系统,并且只有少数基本类型可供选择。因此,使用 typeof 来理解变量中的内容可能会变得很棘手。如果我们的变量保存一个有效的对象,那么我们就会得到对象。但如果它为空,我们仍然会得到对象。认为空引用是一个对象是违反直觉的。</p> <h2> 结论 </h2> <p>毫无疑问,JavaScript 作为一种语言如今非常受欢迎。随着时间的推移,npm 等其他生态系统继续托管大量软件包,JavaScript 只会继续流行。 </p> <p>但是事情已经过去了。无论 null 是一个对象有多么奇怪,或者 JavaScript 会在它认为合适的地方弹出分号,这些系统可能永远不会被弃用、更改或删除。有趣的是,我想说,如果自动分号注入在一夜之间关闭,它可能会导致比 CrowdStrike 更新更大的全球中断。 </p> <p>当然,更改其中一项会对网络造成严重破坏。实际上,让开发人员意识到这些特定的语言怪癖比实际返回并解决原始问题更安全,也可能更实用。 </p> <p>所以,去做正确的选择,别忘了使用分号!</p> <hr> <h2> LogRocket:通过了解上下文更轻松地调试 JavaScript 错误 </h2> <p>调试代码始终是一项乏味的任务。但你越了解自己的错误,就越容易纠正它们。</p> <p>LogRocket 允许您以新的、独特的方式理解这些错误。我们的前端监控解决方案跟踪用户与 JavaScript 前端的互动,使您能够准确查看用户的操作导致了错误。</p><p><img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/172954909986001.jpg?x-oss-process=image/resize,p_40" class="lazy" alt="Six things you may not know about JavaScript"></p> <p>LogRocket 记录控制台日志、页面加载时间、堆栈跟踪、带有标头正文的慢速网络请求/响应、浏览器元数据和自定义日志。了解 JavaScript 代码的影响从未如此简单!</p> <p>免费试用。</p>
以上是关于 JavaScript 你可能不知道的六件事的详细内容。更多信息请关注PHP中文网其他相关文章!

C 和JavaScript通过WebAssembly实现互操作性。1)C 代码编译成WebAssembly模块,引入到JavaScript环境中,增强计算能力。2)在游戏开发中,C 处理物理引擎和图形渲染,JavaScript负责游戏逻辑和用户界面。

JavaScript在网站、移动应用、桌面应用和服务器端编程中均有广泛应用。1)在网站开发中,JavaScript与HTML、CSS一起操作DOM,实现动态效果,并支持如jQuery、React等框架。2)通过ReactNative和Ionic,JavaScript用于开发跨平台移动应用。3)Electron框架使JavaScript能构建桌面应用。4)Node.js让JavaScript在服务器端运行,支持高并发请求。

Python更适合数据科学和自动化,JavaScript更适合前端和全栈开发。1.Python在数据科学和机器学习中表现出色,使用NumPy、Pandas等库进行数据处理和建模。2.Python在自动化和脚本编写方面简洁高效。3.JavaScript在前端开发中不可或缺,用于构建动态网页和单页面应用。4.JavaScript通过Node.js在后端开发中发挥作用,支持全栈开发。

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。 1)C 用于解析JavaScript源码并生成抽象语法树。 2)C 负责生成和执行字节码。 3)C 实现JIT编译器,在运行时优化和编译热点代码,显着提高JavaScript的执行效率。

JavaScript在现实世界中的应用包括前端和后端开发。1)通过构建TODO列表应用展示前端应用,涉及DOM操作和事件处理。2)通过Node.js和Express构建RESTfulAPI展示后端应用。

JavaScript在Web开发中的主要用途包括客户端交互、表单验证和异步通信。1)通过DOM操作实现动态内容更新和用户交互;2)在用户提交数据前进行客户端验证,提高用户体验;3)通过AJAX技术实现与服务器的无刷新通信。

理解JavaScript引擎内部工作原理对开发者重要,因为它能帮助编写更高效的代码并理解性能瓶颈和优化策略。1)引擎的工作流程包括解析、编译和执行三个阶段;2)执行过程中,引擎会进行动态优化,如内联缓存和隐藏类;3)最佳实践包括避免全局变量、优化循环、使用const和let,以及避免过度使用闭包。

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

禅工作室 13.0.1
功能强大的PHP集成开发环境

DVWA
Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

SublimeText3 英文版
推荐:为Win版本,支持代码提示!

SublimeText3汉化版
中文版,非常好用