类型强制、类型转换、类型转换和类型杂耍:所有不同的名称都是指将一种数据类型转换为另一种类型的过程。这个过程几乎存在于每一种编程语言中,是计算机科学中的一个重要概念。
虽然JavaScript被称为最容易的编程语言之一,但当开发者期望JavaScript做一件事而它却返回另一件事时,也会变得令人沮丧。
虽然ECMAScript语言规范标准可以帮助开发者指导他们解决这些问题,但在处理JavaScript中的类型强制时,不阅读和理解规范标准会导致更多的挫败感。
JavaScript中的类型强制是一个例子,说明当我们不清楚它是如何工作的时候,该语言会产生意想不到的结果。每个接触过哪怕是一点点JavaScript代码的人都能体会到,类型强制可能很棘手。
虽然我们在这篇文章中所涉及的代码例子可能看起来像是一个版本更新就能解决的错误,但我们回顾一下为什么类型强制会有这样的行为,是因为许多遗留产品和代码都依赖于旧版本的JavaScript。
这意味着对语言的修改可能会破坏遗留产品和代码,因此我们必须学会如何驾驭类型强制的怪异之处。
在这篇文章中,我们将介绍什么是JavaScript中的类型以及如何使用类型强制,为我们的编程成功做好准备。
JavaScript中的类型
我们可以把JavaScript称为无类型语言,这意味着它没有静态类型。然而,"JavaScript没有类型 "这个著名的神话是错误的。
stringnumberBooleanundefinednullSymbolBigInt
然而,JavaScript中的变量并没有类型。每当我们使用typeof 操作符来返回一个变量的类型时,我们就会返回这个变量的值类型。
现在我们已经澄清了关于JavaScript和类型的一些误解,我们可以了解更多关于类型强制和它在JavaScript中是如何工作的。
类型强制
在JavaScript中,类型强制只能强制到string,number, 和Boolean 原始类型。在JavaScript中,没有办法将一个值类型强制到object 或function 。
JavaScript有两种典型的强制形式:隐式强制和显式强制。
隐式强制是指JavaScript将值的类型强制到引擎盖下的预期类型。这种类型的强制是在开发者不知不觉中发生的。
显式强制发生在我们想把值的类型强制到一个特定的类型时。大多数时候,JavaScript中的显式强制是通过内置函数发生的,比如String(),Number(), 和Boolean() 。
当我们试图在JavaScript中使用不同的值类型来创建操作时,JavaScript会隐含的为我们强制执行值类型。
这就是为什么开发人员倾向于避免在JavaScript中使用隐式强制的原因之一。大多数时候,如果我们不知道JavaScript是如何强制执行值类型的,就会从操作中得到意想不到的结果。
隐式强制并不像开发者倾向于认为的那样糟糕,事实上,它对编写可读但高效的代码很有帮助。要正确理解隐式强制法在JavaScript中的工作原理,关键是要了解它在引擎盖下做了什么。
编号
将原始类型胁迫为数字有很多可能的方法。Number() 函数强制传递给函数的值类型,然后传递给一个数字。当一个类型不能被胁迫为一个数字时,返回的结果是NaN 。
让我们看一下使用Number() 函数进行显式强制的几个例子。
Number("42"); // 42
Number(""); // 0
Number(true); // 1
Number(false); // 0
Number(null); // 0
Number(undefined); // NaN
我们可以清楚地看到一些明显的和意外的结果。将null 转换为一个数字,返回0 ,而将undefined 转换为一个数字,返回NaN 。这两个操作都应该返回NaN ,因为这两个值类型显然都不是有效的数字。
将一个空字符串转换成一个数字会返回0 。这是JavaScript的另一个奇怪的部分,因为这个值类型显然不是一个有效的数字,但它仍然转换为0 。
凯尔-辛普森(Kyle Simpson),这本 你不了解JS系列书籍的作者,他说:"空字符串变成0是所有胁迫行为的根源"。
虽然我们从Number() 函数中得到的结果似乎出乎意料,但ECMAScript规范中明确指出了这些差异性。但如果不读ECMA规范,开发者可能不会意识到这只是JavaScript的写法。
在我们的第一个例子中,我们在null 和undefined 中得到了不同的结果。ECMAScript规范中的 Number()函数带有空值类型,它返回0 ,而每当我们用同样的函数与undefined ,它返回NaN 。
ToNumber 是ECMAScript规范在提到一个值转换为数字的操作时使用的一个类型转换名称。Number() 是JavaScript中的一个原始包装对象,可以将一个值转换为一个数字。这与ToBoolean 相同,我们将在后面介绍。
下面是一个参数的列表,以及ToNumber 操作将它们转换为的结果。
在我们的另一个例子中,我们用一个空字符串使用了Number() 函数,得到了一个0 。这一点在ECMAScript规范中也是明确的。
一个空的或只包含空白的
StringNumericLiteral,会被转换成+0。 -ECMAScript 2015语言规范
字符串
在JavaScript中,要明确地将一个值强制转换成一个字符串,我们可以使用String() 函数。为了隐含地将一个值转换为字符串,我们可以使用+ 操作符,其操作数为字符串。
原始类型会如期转换为字符串。
String("42"); // "42"
String(true); // "true"
String(false); // "false"
String(null); // "null"
String(undefined); // "undefined"
当我们想创建一个操作,而我们的操作数类型之一是字符串时,我们应该小心地使用类型强制法。
JavaScript将我们的操作返回为字符串,而正确的处理方式应该是抛出一个错误,因为没有办法用一个数字和一个字符串进行数学运算,而这不是一个有效数字。
10 + "10" // "1010"
20 + "200" // "20200"
0.212 + "1" // "0.2121"
布尔型
要在JavaScript中明确地将一个值强制为布尔值,我们可以使用Boolean() 函数。为了隐含地将一个值强制为布尔值,我们可以使用逻辑运算符,比如在逻辑上下文中使用||,&&, 和! 。
Boolean() function的规范是非常干净和有帮助的。我们可以清楚地看到,根据我们传递的值的类型,我们会收到哪些结果。
虚假值的列表很容易记住。所有不在列表上的东西都是一个真值。
Boolean('') // false
Boolean(0) // false
Boolean(-0) // false
Boolean(NaN) // false
Boolean(null) // false
Boolean(undefined) // false
Boolean(false) // false
如前所述,逻辑运算符也会将一个值的类型胁迫为布尔值。
true && false // false
true && true // true
true || false // true
true || !false // true
"name" || 0 // "name"
"name" || [] // "name"
"" || [1, 2, 3] // [1, 2, 3]
结论
类型强制是一个核心的JavaScript概念,在每一个使用JavaScript的应用程序、API和服务中都有使用。
总的来说,除非你追求显式强制,否则JavaScript会根据所使用的值类型和操作来隐式强制。但不管是使用隐式还是显式的类型强制,它都为开发者提供了灵活性,并有助于使代码更加可读。
这个简短的概述提供了理解类型强制的基础知识,然而,阅读ECMAScript规范可以对这个概念进行更深入的回顾,以了解为什么会出现意外的类型强制结果。
The postType coercion in JavaScriptappeared first onLogRocket Blog.