在我的数据结构类中,我了解到引擎盖字符串实际上是字符数组,这意味着字符串必须是引用变量而不是原始变量。但是,在JS中并非如此 - 字符串确实被认为是JS中的原始类型。更令人惊讶的是,JS是用C语言编写的,与Python和Ruby一样 - 两者都将字符串作为引用变量。
字符串真的是原始类型吗?如果是这样,这怎么可能?
答案 0 :(得分:3)
是的,字符串真的很原始。那些不是对象的是。用于创建编译器或解释器的语言不需要对编译或解释的语言如何做就有任何影响。
人们有时会被这样一个事实所困惑:尽管它们是原始的,但它们具有属性(如length
)和方法(如toLowerCase
),这使得它们看起来像是对象。所以让我们探讨一下。
当您看到一个表达式访问字符串的属性时,可能是一个方法:
str = str.toLowerCase();
...会发生什么是将字符串原语提升为String
对象,然后使用该对象的方法,然后丢弃临时对象。这是内置于语言中的,在§11.2.1和(更多点到点)§8.7.1中涵盖(粗糙的散文),在步骤1中使用抽象的ToObject
方法。
这适用于大多数基元(字符串,数字和布尔值)。另外两个(null
和undefined
)没有对象等效。
当您将属性分配给原始字符串时,此行为甚至可以正常工作,但由于创建的临时对象被丢弃,该属性会立即消失。例如,这是有效的,将运行:
var str = "foo";
str.someSpecialProperty = "bar";
console.log(typeof str.someSpecialProperty); // "undefined"
...但是添加属性的对象立即消失,使其实际上成为无操作,因此该属性在末尾未定义(因为它不在第二个临时对象上被创造了。)
当我说“嗯,那些不是对象的”是我的意思是你可以明确地创建一个字符串 object :
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>
想要这样做非常罕见,但你可以。