Javascript字符串如何不是对象?

How is a Javascript string not an object?

这不是开玩笑的方式,我真的在问。

道格拉斯·克罗克福德喜欢说,在JavaScript原型面向对象语言中,没有必要使用new

他解释说,添加new只是为了让来自基于类(即"经典")的面向对象编程语言的人感到某种程度的舒适:

JavaScript, We Hardly new Ya

JavaScript is a prototypal language, but it has a new operator that tries to make it look sort of like a classical language. That tends to confuse programmers, leading to some problematic programming patterns.

You never need to use new Object() in JavaScript. Use the object literal {} instead.

好吧,好的:

  • new
  • {}

但后来评论员V_tor de ara_jo指出,这两种情况并不相同。他举了一个例子,说明stringobject不同:

A string object and a string value are not the same thing:

1
2
3
4
5
6
7
8
9
10
11
12
js> p ="Foo"
Foo
js> p.weight = 42
42
js> p.weight // Returns undefined

js> q = new String("Foo")
Foo
js> q.weight = 42
42
js> q.weight
42

The string value cannot have new properties. The same thing is valid for other types.

这里发生了什么事情,一个string不是一个object?我是否将javascript与其他一些语言混淆了,它们都是一个对象?


"一切都是一个物体"…这是语言中存在的最大误解之一。

并不是所有的东西都是一个对象,我们称之为原始值,它们是字符串、数字、布尔值、空值和未定义值。

的确,字符串是一个基值,但是您可以像访问对象一样访问从String.prototype继承的所有方法。

属性访问器运算符(点和括号表示法)临时将字符串值转换为字符串对象,以便能够访问这些方法,例如:

1
"ab".charAt(1); //"b"

幕后发生的事情是这样的:

1
new String("ab").charAt(1); //"b", temporal conversion ToObject

与其他原语值(如BooleanNumber一样,也有对象包装器,它们只是包含原语值的对象,如您的示例中所示:

1
2
3
4
5
var strObj = new String("");
strObj.prop ="foo";

typeof strObj; //"object"
typeof strObj.prop; //"string"

当使用原语时:

1
2
3
4
5
var strValue ="";
strValue.prop ="foo";

typeof strValue; //"string"
typeof strValue.prop; //"undefined"

这是因为上面第二行的属性访问器再次创建了一个新的时间对象,如下所示:

1
2
3
var strValue ="";
new String(strValue).prop ="foo"; // a new object which is discarded
//...