Javascript字符串如何不是对象?

Ian*_*oyd 36 javascript

这不是一个笑话的设置,我真的在问.

Douglas Crockford喜欢说在javascript原型面向对象语言中没有必要new.

他解释说,这new只是为了让人们从基于类(即" 经典 ")的面向对象编程语言中获得某种程度的安慰:

JavaScript,我们很难new

JavaScript是一种原型语言,但它有一个new运算符,试图使它看起来有点像经典语言.这往往会使程序员感到困惑,从而导致一些有问题的编程模式.

您永远不需要new Object()在JavaScript中使用.请改用对象文字{}.

好的:

  • new
  • {}

但是后来评论者VítorDeAraújo指出这两者并不相同.他给出了一个例子,表明a string不像object:

字符串对象和字符串值不是同一个东西:

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
Run Code Online (Sandbox Code Playgroud)

字符串值不能具有新属性.同样的事情对其他类型也有效.

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

CMS*_*CMS 70

"一切都是一个对象" ......这是围绕语言存在的一大误解.

并非 所有东西都是对象,我们称之为原始值,即字符串,数字,布尔值,空值和未定义.

这是真的,字符串是原始值,但您可以访问从String.prototype它继承的所有方法,就像它是一个对象一样.

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

"ab".charAt(1); // "b"
Run Code Online (Sandbox Code Playgroud)

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

new String("ab").charAt(1); // "b", temporal conversion ToObject
Run Code Online (Sandbox Code Playgroud)

与其他原始值一样,例如Boolean,和Number,有对象包装器,它们只是包含原始值的对象,如示例所示:

var strObj = new String("");
strObj.prop = "foo";

typeof strObj; // "object"
typeof strObj.prop; // "string"
Run Code Online (Sandbox Code Playgroud)

虽然有一个原始的:

var strValue = "";
strValue.prop = "foo";

typeof strValue; // "string"
typeof strValue.prop; // "undefined"
Run Code Online (Sandbox Code Playgroud)

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

var strValue = "";
new String(strValue).prop = "foo"; // a new object which is discarded
//...
Run Code Online (Sandbox Code Playgroud)

  • 我想强调的是,当将对象方法用于原始值时,该变量仅被临时*转换为对象,并且在建议的操作之后,该对象被转换回原语.这个概念可能会引起混淆,你可以在[String object vs literal - 修改原型中看到]?(http://stackoverflow.com/q/3756549/258127) (3认同)
  • 我不喜欢在原语中使用大写字母,例如“boolean”和“number”,以避免与对象包装器“Boolean”和“Number”混淆(但 ECMAScript 规范没有这样做)。此外,“NaN”也是一个原始值。 (2认同)