JS:字符串真的是基元类型吗?如果是这样,这怎么可能

JS: Are strings really primitive types? If so, how is this possible?

本文关键字:如果 怎么可能 类型 字符串 真的 JS      更新时间:2023-09-26

在我的数据结构类中,我了解到底层字符串实际上是字符数组,这意味着字符串必须是引用变量而不是原始变量。然而,在JS中情况并非如此 - 字符串在JS中确实被认为是原始类型。更令人惊讶的是,JS是用C编写的,与Python和Ruby相同 - 两者都处理字符串是引用变量。

字符串真的是基元类型吗?如果是这样,这怎么可能?

是的,字符串确实是原始的。好吧,那些不是对象的人是。用于创建编译器或解释器的语言不需要对被编译或解释的语言如何做事产生任何影响。

人们有时会感到困惑,尽管它们是基元,但它们具有属性(如length(和方法(如toLowerCase(,这使得它们看起来像是对象。因此,让我们来探讨一下。

当您看到一个表达式访问字符串的属性时,也许是一个方法:

str = str.toLowerCase();

。发生的情况是,字符串原语被提升为String对象,然后使用该对象的方法,然后丢弃临时对象。这是内置在语言中的,在 §11.2.1 和(更确切地说(§8.7.1 中(更确切地说(§8.7.1 中使用抽象ToObject方法。

这适用于大多数基元(字符串、数字和布尔值(。另外两个(nullundefined(没有对象等价。

当您将属性

分配给基元字符串时,此行为甚至有效,但由于创建的临时对象被丢弃,该属性会立即消失。 例如,这是有效的,并将运行:

var str = "foo";
str.someSpecialProperty = "bar";
console.log(typeof str.someSpecialProperty); // "undefined"

。但是添加属性的对象会立即消失,使其实际上成为无操作,因此属性在末尾未定义(因为它不在创建的第二个临时对象上(。


当我说"好吧,那些不是对象是"时,我的意思是你可以显式创建一个字符串对象

var strObj = new String();

这是一个对象,而不是一个基元:

var str = "foo";
snippet.log("typeof str = " + typeof str);       // "string"
var strObj = new String("foo");
snippet.log("typeof strObj = " + typeof strObj); // "object"
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

想要这样做是非常罕见的,但你可以。