详解JavaScript中的强制类型转换

JavaScript 建立在一系列基本单元之上。你应该对其中的一些已经很熟悉了,比如字符串和数字:

var greet = "Hello"; var year = 89;

字符串和数字是该语言所谓“原语”的一部分。完整清单是:

String

Number

Boolean

Null

Undefined

Object

Symbol (ES6中添加,此处不予介绍)

布尔值用来表示可能是真或假的值。 null 是故意不去赋值,它通常被分配给一个变量,用于表示绑定完毕,稍后将填充有意义的内容。

var maybe = null;

然后才是 undefined,这意味着变量仍然没有被附加上:

var name; console.log(name) undefined

null 和 undefined 看起来非常相似,但它们是两个截然不同的实体,很多开发人员仍然不确定应该使用哪个。

如果要判断 JavaScript 实例的类型,可以用 typeof 运算符。让我们用字符串尝试一下:

typeof "alex" > "string"

还有数字:

typeof 9 > "number"

用于布尔值:

typeof false > "boolean"

undefined:

typeof undefined > "undefined"

还有 null:

typeof null > "object"

结果令人惊讶! null 看起来像一个对象,但实际上它是 JavaScript 中的一个历史性错误,自语言诞生就躺在那里了。 由于这些问题,JavaScript 一直声名狼借。但这仅仅是个开始。

陌生的事情

在 JavaScript 中,在两种类型之间进行转换时有一些奇怪的规则。让我给你一些背景信息。先用 Python 举一个例子。 在 Python 中执行以下指令:

'hello' + 89

会给你一个明确的错误:

TypeError: can only concatenate str (**not** "int") to str

而在 JavaScript 中,只有天空才是你的极限:

'hello' + 89

事实上给出:

"hello89"

如果我们尝试向字符串添加数组,看起来会更加奇怪:

'hello' + []

将会得到

'hello'

还有

'hello' + [89]

会给你一个惊喜:

"hello89"

看起来这种转换背后存在某种逻辑。它甚至适用于存在更多元素的 array :

'hello' + [89, 150.156, 'mike']

得到:

"hello89,150.156,mike"

这两行 JavaScript 足以让 Java 程序员逃离。但是这种行为在 JavaScript 中 100% 是又意义的。因此这种隐式转换,也称为强制类型转换是非常值得探索的。

当一个数字变成一个字符串

一些编程语言有一个叫做类型转换的概念,这意味着:如果我想把一个数字或实例转换为另一种类型,那么我必须使显式转换。它也适用于 JavaScript。请看以下示例:

var greet = "Hello"; var year = 89;

如果我想明确的进行转换,可以在代码中表明意图:

var greet = "Hello"; var year = 89; var yearString = year.toString()

要么这样做:

var greet = "Hello"; var year = 89; var yearString = String(year)

然后我可以连接两个变量:

greet + yearString;

但是在 JavaScript 中有一种被称为隐式转换的微妙机制,由 JavaScript 引擎提供。该语言不会阻止我们对数字和字符串进行加法操作:

'hello' + 89

会得到:

"hello89"

但是这种转换背后的逻辑是什么?你可能会惊讶地发现 JavaScript 中的加法运算符 + 会自动将两个操作数中的任何一个都转换为字符串,如果其中至少有一个是字符串的话!

你会发现更令人惊讶的是,这条规则在ECMAScript规范中一脉相承。 定义了加法运算符的行为,我在这里为你做了总结:

如果 x 是 String 或 y 是String,则返回 ToString(x),然后返回ToString(y)

这个花招只适用于数字吗?并不是。 数组和对象也会受到相同的转换:

'hello' + [89, 150.156, 'mike']

会得到:

"hello89,150.156,mike"

那么下面的代码会得到怎样的结果:

'hello' + { name: "Jacopo" }

要找到答案,你可以通过将对象转换为字符串来进行快速测试:

String({ name: "Jacopo" })

将会得到:

"[object Object]"

所以我有一种感觉:

'hello' + { name: "Jacopo" }

会得到:

"hello[object Object]"

打住!这又是什么?

JavaScript 中 [object Object] 的含义是什么?
“[object Object]” 是最常见的 JavaScript “怪癖”之一。

几乎每个 JavaScript 实例都有一个名为 toString() 的方法,有些方法是由 Object.prototype.toString 提供的。
某些类型(如数组)实现了 toString() 的自定义版本,以便在调用方法时将值转换为字符串。例如 Array.prototype.toString 会覆盖 Object.toString()(也称为 method shadowing)。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/b728cb4f67b886630a18423cdeaa2500.html