JavaScript 数据类型转换-JS中的字符串是不是对象

本文在解释 “JS中的字符串是不是对象” 这个问题之前铺垫了许多前置知识,例如JS数据类型、JS对象、JS数据类型转换。若想直接获得问题的答案,寻找目录中的“总结”查看即可。


JavaScript 数据类型

在MDN官网中,对于“数据结构和类型(Data structures and types)”这一概念是这样介绍的:

MDN

Data types
The latest ECMAScript standard defines eight data types:

  • Seven data types that are primitives:
  1. Boolean. true and false.
  2. null. A special keyword denoting a null value. (Because JavaScript is case-sensitive, null is not the same as Null, NULL, or any other variant.)
  3. undefined. A top-level property whose value is not defined.
  4. Number. An integer or floating point number. For example: 42 or 3.14159.
  5. BigInt. An integer with arbitrary precision. For example: 9007199254740992n.
  6. String. A sequence of characters that represent a text value. For example: "Howdy".
  7. Symbol. A data type whose instances are unique and immutable.
  • and Object

Although these data types are relatively few, they enable you to perform useful operations with your applications. Functions are the other fundamental elements of the language. While functions are technically a kind of object, you can think of objects as named containers for values, and functions as procedures that your script can perform.

最新的 ECMAScript 标准定义了 8 种数据类型:

  • 七种基本数据类型:
  • 布尔值(Boolean),有 2 个值分别是:truefalse
  • null,一个表明 null 值的特殊关键字。JavaScript 是大小写敏感的,因此 nullNullNULL或变体完全不同。
  • undefined,和 null 一样是一个特殊的关键字,undefined 表示变量未赋值时的属性。
  • 数字(Number),整数或浮点数,例如: 42 或者 3.14159
  • 任意精度的整数(BigInt),可以安全地存储和操作大整数,甚至可以超过数字的安全整数限制。
  • 字符串(String),字符串是一串表示文本值的字符序列,例如:"Howdy"
  • 代表(Symbol,在 ECMAScript 6 中新添加的类型)。一种实例是唯一且不可改变的数据类型。
  • 以及对象(Object)。

虽然这些数据类型相对来说比较少,但是通过他们你可以在程序中开发有用的功能。对象和函数是这门语言的另外两个基本元素。你可以把对象当作存放值的一个命名容器,然后将函数当作你的程序能够执行的步骤。


在MDN的描述中,JavaScript的数据类型分类如下:

基本数据类型(Seven data types):Boolean, null, undefined, Number, Bigint, String, Symbol
对象(Object):包含Array,Function等


再来看W3C对于数据类型的解释:

W3C

JavaScript 数据类型
字符串值,数值,布尔值,数组,对象。

JavaScript 数据类型
JavaScript 变量能够保存多种数据类型:数值、字符串值、数组、对象等等:

1
2
3
4
var length = 7;                             // 数字
var lastName = "Gates"; // 字符串
var cars = ["Porsche", "Volvo", "BMW"]; // 数组
var x = {firstName:"Bill", lastName:"Gates"}; // 对象

数据类型的概念
在编程过程中,数据类型是重要的概念。
为了能够操作变量,了解数据类型是很重要的。

ECMAScript 有 5 种原始类型(primitive type),即 Undefined、 Null、 Boolean、 Number 和 String。
原始数据
原始数据值是一种没有额外属性和方法的单一简单数据值。
typeof 运算符可返回以下原始类型之一:

  • string
  • number
  • boolean
  • undefined
    请不要把字符串、数值和布尔值声明为对象!
    如果通过关键词”new”声明JavaScript量,则该变 量会被创建为对象:
1
2
3
4
5
6
var X = new String();
//把x声明为String 对象
>var y = new Number();
//把y声明为Number 对象
var z = new Boolean();
//把z声明为Boolean对象

请避免字符串、数值或逻辑对象。他们会增加代码的复杂性并降低执行速度。
您将在本教程的稍后章节学到更多有关对象的知识。

复杂数据
typeof 运算符可返回以下两种类型之一:

  • function
  • object
    typeof 运算符把对象、数组或 null 返回 object
    typeof 运算符不会把函数返回 object

引用类型通常叫做类(class)。 也就是说,遇到引用值,所处理的就是对象。
本教程会讨论大量的 ECMAScript 预定义引用类型。从现在起,将重点讨论与已经讨论过的原始类型紧密相关的引用类型。

注意:从传统意义上来说,ECMAScript 并不真正具有类。事实上,除了说明不存在类,在 ECMA-262 中根本没有出现“类”这个词。ECMAScript 定义了“对象定义”,逻辑上等价于其他程序设计语言中的类。
提示:本教程将使用术语“对象”。
对象是由 new 运算符加上要实例化的对象的名字创建的。

Object 对象
Object 对象自身用处不大,不过在了解其他类之前,还是应该了解它。因为 ECMAScript 中的 Object 对象与 Java 中的 java.lang.Object 相似,ECMAScript 中的所有对象都由这个对象继承而来,Object 对象中的所有属性和方法都会出现在其他对象中,所以理解了 Object 对象,就可以更好地理解其他对象。


在W3C的描述中,JavaScript的数据类型分类如下:

原始类型(primitive type):Undefined、 Null、 Boolean、 Number 和 String
引用类型(对象)(Object):Object

尽管MDN官网和W3C的官网描述并不完全一致,但可以明确的一点是:尽管在JavaScript中有着 “万物皆对象” 的说法,但依然有非对象的数据类型存在,且原始类型没有属性和方法。最没有争议的原始类型是:Undefined、 Boolean、 Number 和 String。

值得注意的是,虽然 null 有时被认为是一个对象(例如,typeof null 的结果是 'object'),但在实际上,它并不是对象,而是一个原始值。这是JavaScript的一个已知错误。

W3C对于null的解释:

注释:您也许会问,为什么 typeof 运算符对于 null 值会返回 “Object”。这实际上是 JavaScript 最初实现中的一个错误,然后被 ECMAScript 沿用了。现在,null 被认为是对象的占位符,从而解释了这一矛盾,但从技术上来说,它仍然是原始值。


再来看一下MDN和W3C关于“对象”这个概念的介绍:

JavaScript 对象

MDN

MDN对于“对象”的解释:

Introducing JavaScript objects

In JavaScript, most things are objects, from core JavaScript features like arrays to the browser APIs built on top of JavaScript. You can even create your own objects to encapsulate related functions and variables into efficient packages and act as handy data containers. The object-based nature of JavaScript is important to understand if you want to go further with your knowledge of the language, therefore we’ve provided this module to help you.

在 JavaScript 中,大多数事物都是对象,从作为核心功能的字符串和数组,到建立在 JavaScript 之上的浏览器 API 。你甚至可以自己创建对象,将相关的函数和变量高效地封装打包成便捷的数据容器。对于进一步学习 JavaScript 语言知识而言,理解这种面向对象(object-oriented, OO)的特性是必不可少的,所以,我们提供了这个模块来帮助你了解这一切。这里我们会先详细介绍对象的理论和语法,再介绍如何创建对象。
对象基础
对象是一个包含相关数据和方法的集合(通常由一些变量和函数组成,我们称之为对象里面的属性和方法)

每次我们学习的示例使用浏览器内建的 API 和 JavaScript 的一些对象时,我们就在使用对象,因为,这些功能是由跟我们所看到的对象同样的结构来构建的,尽管比我们自己定义的示例要复杂许多。


W3C

W3C对于“对象”的解释:

JavaScript 对象定义

  • JS 历史
  • JS 对象属性
    在 JavaScript 中,对象是王。如果您理解了对象,就理解了 JavaScript。
    在 JavaScript 中,几乎“所有事物”都是对象。
  • 布尔是对象(如果用 new 关键词定义)
  • 数字是对象(如果用 new 关键词定义)
  • 字符串是对象(如果用 new 关键词定义)
  • 日期永远都是对象
  • 算术永远都是对象
  • 正则表达式永远都是对象
  • 数组永远都是对象
  • 函数永远都是对象
  • 对象永远都是对象
    所有 JavaScript 值,除了原始值,都是对象。

JavaScript 原始值
_原始值_指的是没有属性或方法的值。
_原始数据类型_指的是拥有原始值的数据。
JavaScript 定义了 5 种原始数据类型:

  • string
  • number
  • boolean
  • null
  • undefined
    原始值是一成不变的(它们是硬编码的,因此不能改变)。

面向对象术语

对象
ECMA-262 把对象(object)定义为“属性的无序集合,每个属性存放一个原始值、对象或函数”。严格来说,这意味着对象是无特定顺序的值的数组。
尽管 ECMAScript 如此定义对象,但它更通用的定义是基于代码的名词(人、地点或事物)的表示。


每个对象都由类定义,可以把类看做对象的配方。类不仅要定义对象的接口(interface)(开发者访问的属性和方法),还要定义对象的内部工作(使属性和方法发挥作用的代码)。编译器和解释程序都根据类的说明构建对象。

实例
程序使用类创建对象时,生成的对象叫作类的实例(instance)。对类生成的对象的个数的唯一限制来自于运行代码的机器的物理内存。每个实例的行为相同,但实例处理一组独立的数据。由类创建对象实例的过程叫做实例化(instantiation)。
在前面的章节我们提到过,ECMAScript 并没有正式的类。相反,ECMA-262 把对象定义描述为对象的配方。这是 ECMAScript 逻辑上的一种折中方案,因为对象定义实际上是对象自身。即使类并不真正存在,我们也把对象定义叫做类,因为大多数开发者对此术语更熟悉,而且从功能上说,两者是等价的。

对象的构成
在 ECMAScript 中,对象由特性(attribute)构成,特性可以是原始值,也可以是引用值。如果特性存放的是函数,它将被看作对象的方法(method),否则该特性被看作对象的属性(property)。

在 ECMAScript 中,所有对象并非同等创建的。
一般来说,可以创建并使用的对象有三种:本地对象、内置对象和宿主对象。
本地对象
ECMA-262 把本地对象(native object)定义为“独立于宿主环境的 ECMAScript 实现提供的对象”。简单来说,本地对象就是 ECMA-262 定义的类(引用类型)。它们包括:

  • Object
  • Function
  • Array
  • String
  • Boolean
  • Number
  • Date
  • RegExp
  • Error
  • EvalError
  • RangeError
  • ReferenceError
  • SyntaxError
  • TypeError
  • URIError

补充(Java中的数据类型)

如果有了解过Java语言的数据类型会知道:Java有八种基本类型,有byte,short,int,long,double,float,boolean,char。

而在引用数据类型中,定义了它们的包装类,即八种包装类:
Byte(java.lang.Byte(父类Number))
Short(java.lang.Short(父类Number))
Integer(java.lang.Integer(父类Number))
Long(java.lang.Long(父类Number))
Double(java.lang.Double(父类Number))
Float(java.lang.Float(父类Number))
Boolean(java.lang.Boolean(父类Object))
Character(java.lang.Character(父类Object))

需要注意的一点是:Java的基本类型中没有String,String本身就是一个引用数据类型的类。
基本数据类型没有属性和方法,无法进行调用操作,而它们的包装类具有属性和方法,可以调用包装类的属性和方法使用。


当你认为JavaScript的数据类型有对象和Undefined、 Boolean、 Number、 String几个非对象,而对象拥有属性和方法,可以调用,但其他非对象类型则没有属性和方法,不能调用。

别急。还记得JavaScript中的数据类型有隐式转换吗?


JavaScript 数据类型的转换

MDN

下面是MDN对于数据类型转换的解释:

Data type conversion
JavaScript is a dynamically typed language. This means you don’t have to specify the data type of a variable when you declare it. It also means that data types are automatically converted as-needed during script execution.

Numbers and the ‘+’ operator
In expressions involving numeric and string values with the + operator, JavaScript converts numeric values to strings.
With all other operators, JavaScript does not convert numeric values to strings.

Converting strings to numbers
In the case that a value representing a number is in memory as a string, there are methods for conversion.

  • parseInt()
  • parseFloat()
    parseInt only returns whole numbers, so its use is diminished for decimals.
    Note: Additionally, a best practice for parseInt is to always include the radix parameter. The radix parameter is used to specify which numerical system is to be used.
    An alternative method of retrieving a number from a string is with the + (unary plus) operator.

数据类型的转换
JavaScript 是一种动态类型语言 (dynamically typed language)。这意味着你在声明变量时可以不必指定数据类型,而数据类型会在代码执行时会根据需要自动转换。

数字转换为字符串
在包含的数字和字符串的表达式中使用加法运算符(+),JavaScript 会把数字转换成字符串。

在涉及其他运算符时,JavaScript 语言不会把数字变为字符串。

字符串转换为数字
有一些方法可以将内存中表示一个数字的字符串转换为对应的数字。

  • parseInt() (en-US)
  • parseFloat()
    parseInt 方法只能返回整数,所以使用它会丢失小数部分。另外,调用 parseInt 时最好总是带上进制(radix)参数,这个参数用于指定使用哪一种进制。
    将字符串转换为数字的另一种方法是使用一元加法运算符

W3C

W3C对于数据类型转换的解释:

JavaScript 拥有动态类型,这意味着相同变量可用作不同类型。
W3C中详细介绍数据类型转换的相关链接:https://www.w3school.com.cn/js/pro_js_typeconversion.asp


现在已经知道了JavaScript中的数据类型、对象、以及数据类型转换的概念后,再来看看下面这个例子:

示例一

在VSCode中输入以下代码:

1
2
3
4
5
6
7
<script>
var a = "abcdefg";
console.log(a);
var b = a.substring(2);
console.log(a);
console.log(b);
</script>

在这个例子中,变量a为一个基本类型的字符串,a此时应当为一个基本类型的string。
后面调用了a的substring方法。

运行后得到的结果为:

1
2
3
abcdefg
abcdefg
cdefg

由结果第三行可知,调用a的方法成功了。
似乎和前面的结论相悖:一个基本类型的a竟可以调用方法。

示例二

JS中有“原型”和“原型链”这样的概念。我们利用原型链的特性再来看一个例子。

在浏览器的开发者模式中,可以在控制台输入JS代码并运行。

在控制台中输入下面的内容:

1
2
a="aaa"
a.__proto__

输入完毕后回车,可以得到下面的结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
String {'', constructor: ƒ, anchor: ƒ, at: ƒ, big: ƒ, …}

anchor: ƒ anchor()
at: ƒ at()
big: ƒ big()
blink: ƒ blink()
bold: ƒ bold()
charAt: ƒ charAt()
charCodeAt: ƒ charCodeAt()
codePointAt: ƒ codePointAt()
concat: ƒ concat()
constructor: ƒ String()
endsWith: ƒ endsWith()
fixed: ƒ fixed()
fontcolor: ƒ fontcolor()
fontsize: ƒ fontsize()
includes: ƒ includes()
indexOf: ƒ indexOf()
isWellFormed: ƒ isWellFormed()
italics: ƒ italics()
lastIndexOf: ƒ lastIndexOf()
length: 0
link: ƒ link()
localeCompare: ƒ localeCompare()
match: ƒ match()
matchAll: ƒ matchAll()
normalize: ƒ normalize()
padEnd: ƒ padEnd()
padStart: ƒ padStart()
repeat: ƒ repeat()
replace: ƒ replace()
replaceAll: ƒ replaceAll()
search: ƒ search()
slice: ƒ slice()
small: ƒ small()
split: ƒ split()
startsWith: ƒ startsWith()
strike: ƒ strike()
sub: ƒ sub()
substr: ƒ substr()
substring: ƒ substring()
sup: ƒ sup()
toLocaleLowerCase: ƒ toLocaleLowerCase()
toLocaleUpperCase: ƒ toLocaleUpperCase()
toLowerCase: ƒ toLowerCase()
toString: ƒ toString()
toUpperCase: ƒ toUpperCase()
toWellFormed: ƒ toWellFormed()
trim: ƒ trim()
trimEnd: ƒ trimEnd()
trimLeft: ƒ trimStart()
trimRight: ƒ trimEnd()
trimStart: ƒ trimStart()
valueOf: ƒ valueOf()
Symbol(Symbol.iterator): ƒ [Symbol.iterator]()
[[Prototype]]: Object
[[PrimitiveValue]]: ""

在输出信息的导数第二行中看到这样一条:

1
[[Prototype]]: Object

也就是在a="aaa"中,a的类型为String,但String却属于Object。

这是为什么呢?这个String到底是不是对象呢?如果是对象,为什么会将String称为基本类型/原始类型?如果不是对象,为什么能够调用它的方法呢?

JS中的字符串是不是对象

这个问题可以先参考下面这样一个帖子:
《js中的字符串是对象吗?》

在第一个回答中:(以下为摘录)

为了便于操作基本类型值,ECMAScript 还提供了 3 个特殊的引用类型:Boolean、Number 和 String。这些类型与本章介绍的其他引用类型相似,但同时也具有与各自的基本类型相应的特殊行为。

实际上,每当读取一个基本类型值的时候,后台就会创建一个对应的基本包装类型的对象,从而让我们 能够调用一些方法来操作这些数据。来看下面的例子。

1
2
var s1 = "some text";
var s2 = s1.substring(2);

这个例子中的变量 s1 包含一个字符串,字符串当然是基本类型值。而下一行调用了 s1 的subString()方法,并将返回的结果保存在了 s2 中。
我们知道,基本类型值不是对象,因而从逻辑上讲它们不应该有方法(尽管如我们所愿,它们确实有方法)。

其实,为了让我们实现这种直观的操作,后台已经自动完成了一系列的处理。
当第二行代码访问 s1 时,访问过程处于一种读取模式,也就是要从内存中读取这个字符串的值。

而在读取模式中访问字符串时,后台都会自动完成下列处理。
(1) 创建 String 类型的一个实例;
(2) 在实例上调用指定的方法;
(3) 销毁这个实例。

可以将以上三个步骤想象成是执行了下列 ECMAScript 代码:

1
2
3
var s1 = new String("some text"); 
var s2 = s1.substring(2);
s1 = null;

经过此番处理,基本的字符串值就变得跟对象一样了。而且,上面这三个步骤也分别适用于 Boolean 和 Number 类型对应的布尔值和数字值。

引用类型与基本包装类型的主要区别就是对象的生存期。
使用 new 操作符创建的引用类型的实例, 在执行流离开当前作用域之前都一直保存在内存中。而自动创建的基本包装类型的对象,则只存在于一 行代码的执行瞬间,然后立即被销毁

这意味着我们不能在运行时为基本类型值添加属性和方法。来看 下面的例子:

1
2
3
var s1 = "some text"; 
s1.color = "red";
alert(s1.color); //undefined

在此,第二行代码试图为字符串 s1 添加一个 color 属性。
但是,当第三行代码再次访问 s1 时, 其 color 属性不见了。

问题的原因就是第二行创建的 String 对象在执行第三行代码时已经被销毁了。
第三行代码又创建自己的 String 对象,而该对象没有 color 属性。
当然,可以显式地调用 Boolean、Number 和 String 来创建基本包装类型的对象。

不过,应该在 绝对必要的情况下再这样做,因为这种做法很容易让人分不清自己是在处理基本类型还是引用类型的 值。
对基本包装类型的实例调用 typeof 会返回”object”,而且所有基本包装类型的对象都会被转换为布尔值 true。 Object 构造函数也会像工厂方法一样,根据传入值的类型返回相应基本包装类型的实例。

例如:

1
2
var obj = new Object("some text"); 
alert(obj instanceof String); //true

把字符串传给 Object 构造函数,就会创建 String 的实例;而传入数值参数会得到 Number 的实 例,传入布尔值参数就会得到 Boolean 的实例。
要注意的是,使用 new 调用基本包装类型的构造函数,与直接调用同名的转型函数是不一样的。

例如:

1
2
3
4
5
var value = "25";
var number = Number(value); //转型函数
alert(typeof number); //"number"
var obj = new Number(value); //构造函数
alert(typeof obj); //"object"

在这个例子中,变量 number 中保存的是基本类型的值 25,而变量 obj 中保存的是 Number 的实 例。
尽管我们不建议显式地创建基本包装类型的对象,但它们操作基本类型值的能力还是相当重要的。 而每个基本包装类型都提供了操作相应值的便捷方法。

作者:Chess
链接:https://www.zhihu.com/question/420346414/answer/1464146126
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


MDN中也有部分内容提到了这个特性:

JavaScript data types and data structures
Programming languages all have built-in data structures, but these often differ from one language to another. This article attempts to list the built-in data structures available in JavaScript and what properties they have. These can be used to build other data structures.
The language overview offers a similar summary of the common data types, but with more comparisons to other languages.
Dynamic and weak typing
JavaScript is a dynamic language with dynamic types. Variables in JavaScript are not directly associated with any particular value type, and any variable can be assigned (and re-assigned) values of all types:

1
2
3
let foo = 42; // foo is now a number
foo = "bar"; // foo is now a string
foo = true; // foo is now a boolean

JavaScript is also a weakly typed language, which means it allows implicit type conversion when an operation involves mismatched types, instead of throwing type errors.

1
2
3
const foo = 42; // foo is a number
const result = foo + "1"; // JavaScript coerces foo to a string, so it can be concatenated with the other operand
console.log(result); // 421

Implicit coercions is very convenient, but can be a potential footgun if developers didn’t intend to do the conversion, or intend to convert in the other direction (for example, string to number instead of number to string). For symbols and BigInts, JavaScript has intentionally disallowed certain implicit type conversions.

Primitive values
All types except Object define immutable values represented directly at the lowest level of the language. We refer to values of these types as primitive values.
All primitive types, except null, can be tested by the typeof operator. typeof null returns "object", so one has to use === null to test for null.
All primitive types, except null and undefined, have their corresponding object wrapper types, which provide useful methods for working with the primitive values. For example, the Number object provides methods like toExponential(). When a property is accessed on a primitive value, JavaScript automatically wraps the value into the corresponding wrapper object and accesses the property on the object instead. However, accessing a property on null or undefined throws a TypeError exception, which necessitates the introduction of the optional chaining operator.

Type typeof return value Object wrapper
Null "object" N/A
Undefined "undefined" N/A
Boolean "boolean" Boolean
Number "number" Number
BigInt "bigint" BigInt
String "string" String
Symbol "symbol" Symbol

The object wrapper classes’ reference pages contain more information about the methods and properties available for each type, as well as detailed descriptions for the semantics of the primitive types themselves.

动态和弱类型
JavaScript 是一种有着动态类型的动态语言。JavaScript 中的变量与任何特定值类型没有任何关联,并且任何变量都可以分配(重新分配)所有类型的值:

1
2
3
let foo = 42; // foo 现在是一个数值
foo = "bar"; // foo 现在是一个字符串
foo = true; // foo 现在是一个布尔值

JavaScript 也是一个弱类型语言,这意味着当操作涉及不匹配的类型是否,它将允许隐式类型转换,而不是抛出一个错误。

1
2
3
const foo = 42; // foo is a number
const result = foo + "1"; // JavaScript coerces foo to a string, so it can be concatenated with the other operand
console.log(result); // 421

强制隐式转换是非常方便的,但是如果开发者不打算转换,或者打算向另一个方向转换(例如,字符串转数值而不是数值到字符串),则会存在潜在的隐患。对于 symbol 和 BigInt, JavaScript 总是不允许某些隐式类型转换。

原始值
除了 Object 以外,所有类型都定义了表示在语言最低层面的不可变值。我们将这些值称为_原始值_。
除了 null,所有原始类型都可以使用 typeof运算符测试。typeof null 返回 "object",因此必须使用 === null 来测试 null
除了 nullundefined,所有原始类型都有它们相应的对象包装类型,这为处理原始值提供可用的方法。例如,Number 对象提供向 toExponential() 这样的方法。当在原始值上访问属性时,JavaScript 会自动将值包装到相应的包装对象中,并访问对象上的属性。然而,在 nullundefined 上访问属性时,会抛出 TypeError 异常,这需要采用可选链运算符。

类型 typeof 返回值 对象包装器
Null "object" N/A
Undefined "undefined" N/A
Boolean "boolean" Boolean
Number "number" Number
BigInt "bigint" BigInt
String "string" String
Symbol "symbol" Symbol

对象包装器类的参考页面包含关于每个类型可用方法和属性类型的更多用法,以及原始类型本身的详细描述。


总结

String,Number,Boolean类型不是对象,而是基本数据类型,但在读取这个基本类型的值的时候,JS引擎会将这些基础类型进行隐式类型转换,转换成它们相应的对象包装类型,而对象包装类型可以调用相关的属性和方法。

笔者的总结未必是准确的,了解详情还请仔细查看上文。


其他解释

但W3C给出了一个与MDN完全不相关的回答。
笔者也无法判断W3C的解释是否合理或正确,但也将W3C的解释贴出来,如果有了解这方面的老师还请留下评论。

W3C的解释

所有程序设计语言最重要的特征之一是具有进行类型转换的能力。
ECMAScript 给开发者提供了大量简单的类型转换方法。
大部分类型具有进行简单转换的方法,还有几个全局方法可以用于更复杂的转换。无论哪种情况,在 ECMAScript 中,类型转换都是简短的一步操作。
转换成字符串
ECMAScript 的 Boolean 值、数字和字符串的原始值的有趣之处在于它们是伪对象,这意味着它们实际上具有属性和方法。
例如,要获得字符串的长度,可以采用下面的代码:

1
2
var sColor = "red";
alert(sColor.length); //输出 "3"

尽管 “red” 是原始类型的字符串,它仍然具有属性 length,用于存放字符串的大小。
总而言之,3 种主要的原始类型 Boolean 值、数字和字符串都有 toString() 方法,可以把它们的值转换成字符串。
提示:您也许会问,“字符串还有 toString() 方法吗,这不是多余吗?”是的,的确如此,不过 ECMAScript 定义所有对象都有 toString() 方法,无论它是伪对象,还是真对象。因为 String 类型属于伪对象,所以它一定有 toString() 方法。
相关链接:ECMAScript 类型转换
https://www.w3school.com.cn/js/pro_js_typeconversion.asp

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

You Found Me.

支付宝
微信