Javascript字符串如何不是对象?

时间:2010-10-11 15:25:20

标签: javascript

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

Douglas Crockford is fond of saying在javascript原型面向对象语言中,不需要new

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

  

JavaScript, We Hardly new Ya

     

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

     

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

好的,好的:

  • new不好
  • {}

然后是评论者Vítor De Araújo pointed out that the two are not the same。他举例说明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
     

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

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

2 个答案:

答案 0 :(得分:67)

“一切都是一个对象” ......这是整个语言中存在的一个重大误解。

一切是一个对象,我们称之为原始值,它们是字符串,数字,布尔值,空值和未定义

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

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

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

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

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

与其他原始值一样,例如BooleanNumber,还有对象包装器,它们只是包含原始值的对象,就像在您的例如:

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

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

使用原语:

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

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

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

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

答案 1 :(得分:1)

字符串和对象之间最重要的区别是对象必须遵循this rule for the == operator

  

仅当操作数引用时,比较对象的表达式才为true   相同的对象。

因此,尽管字符串具有方便的==来比较值,但是在使任何其他不可变对象类型表现得像值类型时,您还是很不走运。 (也可能存在其他差异,但这是每天引起JavaScript开发人员兴奋的唯一差异)。例子:

"hello" == "hello"
-> true
new String("hello") == new String("hello") // beware!
-> false