类型

类型转换 属于 JavaScript

2 个练习

关于 类型转换

在 JavaScript 中,值可以有不同的类型。通过显式的_类型转换_可以改变变量的类型。 除此之外,当上下文需要时,JavaScript 还会执行_类型强制转换_(隐式类型转换)。

类型转换

JavaScript 不像许多其他语言那样有强制转换为(另一种)类型的语法结构,但可以使用一些内置的辅助方法。 最值得注意的是,全局对象 Boolean、Number 和 String 可以当作函数使用,把值转换成对应的类型。

转换为布尔值(真值/假值)

用 Boolean(value) 可以把任何值转换为布尔值。 这是怎么做到的?

有一组固定的值,称为_假值_,它们会被转换为 false。 最重要的是,false、0、空字符串、null、undefined 和 NaN 都是假值。 MDN 上关于 “Falsy” 的文章列出了完整的清单。

对于所有其他值,Boolean 返回 true。 这些值称为_真值_。

Boolean(-1);
// => true

Boolean(0);
// => false

Boolean(' ');
// => true

Boolean('');
// => false

注意,根据上述规则,在 JavaScript 中 '0'、'false'、[] 和 {} 都是真值。

转换为数字

Number(value) 可以用来把值转换为数字。 字符串开头和结尾的空白符会被忽略,空字符串会被转换为 0。 如果你尝试转换非原始值,或者一个不表示数字的字符串,不会抛出错误。 结果会是 NaN(Not-A-Number)。

Number('  -12.34  ');
// => -12.34

Number('1,2');
// => NaN

Number('1 2');
// => NaN

Number('');
// => 0

Number('10e3');
// => 10000

Number({ key: '123' });
// => NaN

下面是 Number 对其他原始值返回的结果。

Number(true);
// => 1

Number(false);
// => 0

Number(null);
// => 0

Number(undefined);
// => NaN

注意,与上一个例子不同,不带任何实参调用 Number() 被定义为返回 0。

JavaScript 还提供了 parseInt 和 parseFloat 两个函数。 它们对于哪些字符串可以转换为数字的规则更宽松。 因此,最好优先使用 Number 作为转换函数,以避免意外结果。

parseInt('123a45');
// => 123

Number('123a45');
// => NaN

转换为字符串

用 String(value) 可以把值转换为字符串。 对于原始值,结果和你预期的一样。

String(12.34);
// => '12.34'

String(false);
// => 'false'

String(null);
// => 'null'

String(undefined);
// => 'undefined'

对于数组,String 函数会为每个元素应用字符串转换,并用逗号把结果连接起来。 你也可以自己调用 join 方法,比如自定义分隔符。 不过,在这些情况下,null 和 undefined 会被转换为空字符串。

String([42, null, true, 'abc']);
// => '42,,true,abc'

对于对象,默认情况下 String 会返回一段没什么用的文本。

String({ key: 'value' });
// => '[object Object]'

你可以自定义转换行为,比如提供一个 toString 方法。 javascript.info 上的“对象到原始值的转换”一节解释了细节。

为对象和数组获得更好的字符串表示的另一种常见方法是使用 JSON 编码。 你可以用 JSON.stringify 把它转换成字符串,再用 JSON.parse 转回对象或数组。

const obj = {
  name: 'Gilda Guerra',
  address: {
    city: 'Goiânia',
  },
};

JSON.stringify(obj);
// => '{"name":"Gilda Guerra","address":{"city":"Goiânia"}}'

类型强制转换

在某些上下文中,JavaScript 会在求值某条语句之前自动把值转换为另一种数据类型。 这种隐式转换称为_类型强制转换_。

布尔上下文

当值用在布尔上下文中时,JavaScript 会应用与 Boolean 函数相同的规则来隐式转换该值。

  • 当 if 语句的条件不是布尔值时,会应用强制转换来判断条件是否成立。 同样适用于三元运算符 ? 的第一个操作数。

    const num = 0;
    if (num) {
      // this block is NOT executed because 0 is falsy
    }
    
    const name = 'Jin';
    name ? 'name was provided' : 'no name provided';
    // => 'name was provided'
    
  • 逻辑非运算符 ! 的操作数在应用非运算之前也会被强制转换为布尔值。

    const name = '';
    !name;
    // => true
    

    上述行为的一个结果是,!!value 与 Boolean(value) 的效果相同。 尽管如此,为了提高可读性,你应该使用 Boolean。

  • JavaScript 也会对逻辑与(&&)和逻辑或(||)运算符的操作数应用强制转换。 但请记住,表达式的结果不一定是布尔值。 它会返回其中一个原始操作数(参见 MDN 上的逻辑运算符)。

    null || 'hello';
    // => 'hello'
    

字符串上下文

如果加法运算符 + 用于原始值,并且其中一个操作数是字符串,那么另一个操作数也会被强制转换为字符串。 转换逻辑与使用 String 函数时相同。 之后,两个字符串会被拼接起来。

let name;
'hello ' + name;
// => 'hello undefined'

对于嵌入模板字符串中的非字符串值,也会发生同样的隐式转换。

const degrees = 23;
`It is ${degrees} °C`;
// => 'Is is 23 °C.';

数值上下文

许多运算符会按照上面解释的 Number 函数的逻辑,把操作数强制转换为数字(如有必要)。

  • 算术运算符:+(如果不涉及字符串)、-、*、/、%、**
  • 一元加号运算符和一元取负运算符:+、-
  • 关系运算符(用于非字符串操作数):>、>=、<、<=
  • 位运算符:|、&、^、~

关于这些运算符的更多细节,请参阅 MDN 的运算符列表。

当操作数可能是字符串时,最好始终用 Number 函数显式转换,以免出错。

'1' + '2';
// => '12'
// addition operator in string context as explained above

Number('1') + Number('2');
// => 3

有时你会看到用一元加号运算符把字符串强制转换为数字。 不推荐这样做,因为它比显式调用 Number 难读得多。

const value = '42';
+value;
// => 42

Number(value);
// => 42

使用宽松相等和不相等运算符 ==/!= 时,也常常涉及隐式转换为数字。 不过,这些运算符的确切逻辑相当复杂(参见 MDN 上的宽松相等)。 结果难以预测,有时并不符合你的预期。 请改用严格相等/不相等运算符 ===/!==,以避免这些隐式转换。

通过 GitHub 编辑 该链接会在新窗口或标签页中打开

学习 类型转换