字符串是对象吗?

12

以下是认为字符串是对象的两个原因。首先,您可以通过以下方式创建字符串:

var mystring = new String("asdf");

我认为使用new操作符后的构造函数必须返回一个对象。其次,字符串似乎具有属性和方法。例如:

mystring.toUpperCase();

但是,如果字符串是对象,那么我们期望以下内容可以工作:

function string_constructor() {
    return "asdf";
}

var mystring = new string_constructor();

但是它并没有,而且我被告知它并没有,因为字符串不是对象。那么字符串是对象还是不是?无论如何,我如何理解我列出的所有内容?


3
JavaScript 中的字符串是对象。 - mplungjan
在荷兰我们说:“言简意赅”,但这是一个答案,不是评论。^^ - user142019
1
谢谢。我回答了。更长,更强大。 - mplungjan
1
但是在JavaScript中,字符串不一定是对象。特别是字符串常量不是对象-它们是值。然而,当必要时,它们会自动转换为“String”对象。 - Pointy
6个回答

24

说到语言类型,字符串是的字符串类型。

该语言有五种原始类型,它们分别是字符串数字布尔未定义

还有字符串对象(也适用于数字或布尔值),它们被称为原始包装器,当您使用与它们相关联的构造函数时创建,例如:

typeof new String('foo'); // "object"
typeof 'foo';             // "string"

但不要被它们搞混了,你很少需要使用原始包装器,因为即使原始值不是对象,你仍然可以访问它们继承的属性。例如,在字符串上,你可以访问String.prototype的所有成员,比如:
'foo'.indexOf('o'); // 2

这是因为属性访问器(在这种情况下是点)临时将原始值转换为对象,以便能够解析原型链中的indexOf属性。
关于你问题中的构造函数,正如你所知道的,它不会返回字符串。
使用new运算符调用的函数会返回一个隐式值,该值是从该函数的原型继承而来的新对象,例如:
function Test () {
  // don't return anything (equivalent to returning undefined)
}

new Test() instanceof Test; // true, an object

如果从构造函数返回一个对象,那么新创建的对象(构造函数内部的this)将会丢失,因此显式返回的对象将会成为函数的输出结果。
function Test2() {
  return {foo: 'bar'};
}

new Test2().foo; // 'bar'

但是在原始值的情况下,它们会被忽略掉,并且构造函数中的新对象会隐式返回(更多细节请查看[[Construct]]内部操作,参见第9和10步)。

在JavaScript中,语言类型名称是大写的。5种原始类型包括:数字(Number)、字符串(String)、布尔值(Boolean)、空(Null)和未定义(Undefined)。 - Šime Vidas
你说:字符串是值。但你也必须说明它属于哪种类型。每个值都有一个类型。 - Šime Vidas
@Šime:是的,现在澄清了。谢谢 :) - Christian C. Salvadó

3
在JavaScript中,字符串有两种类型:
  1. String语言类型包含像"foo"'bar'这样的值。这些值是原始值。阅读String类型介绍

  2. 然后有一个String构造函数。(构造函数是用于创建某个“类”(或伪类)的新实例的函数对象)。所以这个:new String("foo")将创建一个新的对象(一种Object类型的值),其中包含原始值"foo"。阅读String构造函数介绍

实际上,你不使用new String('foo')表示法,而是使用字符串字面表示法'foo'

回答您的问题:

在JavaScript中,字符串不是对象。它们是原始值。但是,存在可以用于存储字符串值的String对象,但这些String对象在实践中并不常用。


1
原始字符串在JavaScript中的行为类似于对象,因为当您调用对象方法时它们会自动转换为对象:

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String

可以通过调用构造函数new String()来创建字符串对象。String对象使用下面描述的方法包装了JavaScript的字符串原始数据类型。全局函数String()也可以在前面不加new的情况下被调用以创建一个原始字符串。在JavaScript中,字符串字面量是原始字符串。
由于JavaScript自动在字符串原始值和String对象之间进行转换,因此您可以在字符串原始值上调用String对象的任何方法。JavaScript会自动将字符串原始值转换为临时String对象,调用该方法,然后丢弃临时String对象。例如,您可以在从字符串字面量创建的字符串原始值上使用String.length属性。

你的回答自相矛盾... "在JavaScript中,字符串肯定是对象:" ... "JavaScript中的字符串字面量是原始字符串。" - jondavidjohn
已经修正 - 我应该说:肯定表现得像对象,因为这里的人太苛刻了。 - mplungjan
那并没有回答问题。问题是:“字符串是对象吗?”你的回答暗示了字符串不是对象,但你必须明确表述。 - Šime Vidas
好的。所以+1为你的答案。至少我贴出了官方信息-迄今为止没有其他人这样做。 - mplungjan

0

字符串是对象,但你在例子中所做的并不是创建一个新的字符串。通过使用“new”,你正在创建一个对象实例,而不是一个“字符串”。

var F = function() {
    return 'c';
};
var a = new String('a');
var b = 'b';
var c  = new F();
alert("a is: " + typeof a + ", b is: " + typeof b + ", c is: " + typeof c);
// alerts: a is: object, b is: string. c is: object

不管是字符串,数组,还是“简单”对象,在编程中都不应该使用'new'。


1
你说字符串是对象,但你的演示显示变量b是一个字符串而不是一个对象(这与你最初的陈述相矛盾)。 - Šime Vidas
语义又卡了我一次!一个字符串是类型为“string”的对象,而a和b生成类型为“object”的对象。 - veddermatic

0

字符串既是基本类型,也是对象类型。可以想象一下像Java中的Integer、Float和Char这样的真正的对象类,它们对应于int、float和char。


0

String是原始字符串数据类型的包装器。当您执行类似var s = "My String"的操作时,需要时会在幕后创建一个String包装对象。

然而有趣的是,typeof s = 'string'而不是'object'。有人知道为什么吗?


当字符串常量被赋值给一个变量时,只有在必要的情况下才会创建“String”包装对象,而不是简单地创建它。 - Pointy
因为s是String类型的值,而不是Object类型的值(很明显)。不要纠缠于String对象包装器,它在实践中并不常用。 - Šime Vidas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接