js隐式转换过程(js隐士类型转换)

面向对象的语言常常以「一切皆对象」的思想为基础。然而,在对象系统中,会出现这样一个问题:如何统一基础类型(例如 Number)和对象类型之间的关系?

为了实现「一切皆对象」的理念,JavaScript 在类型系统上做出了一些妥协。其结果是,它为一些基础类型引入了对应的包装类(Number、Boolean、String),将值类型数据包装成对象来进行处理。
JavaScript 为了提高数据的处理效率,保留了一部分基础类型,这样的设计使得 JavaScript 并不像 Java 那样成为一种纯粹的面向对象语言。
const num = 123;const numObj = new Number(123);console.log(typeof num) //numberconsole.log(typeof numObj) //object
需要注意的是,尽管 num 和 numObj 的值相等,但它们是不同的类型。num 是一个原始的数值类型,而 numObj 是一个对象类型(Number 对象)。首先它们在内存中的表示和操作方式不同;其次你可以对 numObj 这样的对象调用 Number 对象的方法,而不能直接在 num 上调用这些方法。
这种包装类的机制使得 JavaScript 可以将值类型数据作为对象处理,同时保留了基础类型系统以提高性能和效率。
隐式的数据转换规则
JavaScript 保留了基础值类型,我们在将对象转换为数字或字符串过程的时候,其实是直接与对象的 valueOf() 和 toString()方法相关。
例:如果我们尝试将对象转换为字符串,首先会尝试使用对象的 toString() 方法,如果该方法不存在或者返回的结果不是一个有效的字符串,那么会接着尝试使用 valueOf() 方法;
例:如果我们试图将对象转换为数字,首先会尝试使用 valueOf() 方法,如果该方法不存在或者返回的结果不是一个有效的数字,那么会接着尝试调用 toString() 方法。
换句话说,无论我们期望将对象转换为字符串还是数字,都会依次尝试使用 valueOf() 和 toString() 方法。
预期的转换结果是什么
由于 valueOf() 和 toString() 的调用顺序与「转换的预期」有关,所以,那什么才是转换的结果?
并没有文档来说明操作数与运算符或者函数设计不一致的时候,JavaScript 对于这个设定是哪种预期。
parseInt(x)
在有些情况下比较显而易见,比如 parseInt() 这个函数,它显然试图将 x 理解为字符串,因此如果 x 是对象,那么它将先调用 toString()。
Math.abs(x)
而 Math.abs(x) 则明显会将 x 先理解为数值,所以对同样的 x 对象来说,上面的例子优先使用 x.valueOf()。
然而,有些运算符或函数调用的预期却不那么明显,我们一直在讨论的「加号+」运算符就是其中之一,事实上我们并不能主观的假设,它会将两个操作数预期为数值还是字符串。
而在没有任何预期的情况下,JavaScript 会优先使用「先 valueOf() ,后 toString()」这一顺序,也就是说,隐式的、默认的以 x. valueOf() 为优先。
加号+ 是怎样转换的?
在对象到值的转换时,默认的是 valueOf() 优先,而在加号+运算的时候却默认字符串优先,二者正好不同,所以我们来看个 … 示例:
const x = new Number(1) console.log(1 + x) // 2 console.log(\\’1\\’ + x) //11
在整个运算中,顺序地执行了两条规则:
1、当 x 是对象时,先将 x 转换到值,并由 x.valueOf() 优先,返回数值 1;
2、当「加号+」运算中发现字符串时,由字符串连接优先得到11;
在默认情况下,JavaScript 会首先尝试调用 valueOf() 方法来将对象转换为一个原始值。然而,在大多数情况下,valueOf() 方法的返回值不会符合预期,因此会被忽略。那 …
valueOf()到底在执行什么
当 x 是对象时,使用 valueOf() 方法,它会尝试从对象中获取一个原始值。
该方法首先检查对象本身是否有 valueOf() 方法的定义。如果有定义,则会调用该方法并返回其结果。这个结果可以是任何类型的值,包括字符串、数字、布尔值等。
然而,需要注意的是,valueOf() 方法的返回值可能不符合预期。默认情况下,x.valueOf() 返回对象 x 自身,根据对象的类型和具体实现,valueOf() 方法可能返回 undefined、null,甚至是另一个对象。
在 JavaScript 中,当进行隐式类型转换时,valueOf() 方法的返回值往往会被忽略,因为引用类型的数据(如Object、Error、RegExp、Function对象等)的valueOf()方法并不能返回一个有效的值。
根据隐式转换的规则,JavaScript会尝试调用对象的 toString() 方法来获取一个字符串值,以便进行值运算或其他操作。所以,在这种情况下,JavaScript 会忽略 valueOf() 方法的结果,而是尝试调用toString()方法来获取一个字符串值。

题图授权:Pixabay
内容优化:ChatGPT
内容来源:《JavaScript 语言精髓与编程实战》

原创文章,作者:小道研究,如若转载,请注明出处:https://www.sudun.com/ask/34617.html

(0)
小道研究's avatar小道研究
上一篇 2024年4月11日 下午9:43
下一篇 2024年4月11日 下午9:45

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注