Javascript 字符串如何不是对象?

IT技术 javascript
2021-02-08 09:53:56

这不是开玩笑的设置,我真的在问。

Douglas Crockford 喜欢说在 javascript 原型面向对象语言中不需要new.

他解释说,这new只是为了让来自基于类(即“经典”)面向对象的编程语言的人们在一定程度上感到舒适:

JavaScript中,我们很难new

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

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

好的:

  • new 坏的
  • {} 好的

但随后评论员Vítor De Araújo 指出,两者并不相同他举了一个例子来说明 astring不像 an 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而不是 an object我是否将 javascript 与其他一些语言混淆了,其中一切都是对象?

2个回答

“一切都是对象” ……这是围绕语言存在的最大误解之一。

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

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

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

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

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

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

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

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
//...
啊,是的,Infinity我已经以为我忘记了其他一些value。怎么会忘记Infinity呢?
2021-03-26 09:53:56
即使两年后,这个答案仍然有效!+1!!
2021-03-26 09:53:56
Marcel,是的,对象包装器会引起混淆,例如if (new Boolean(false)) {alert(':D');}. 是的,NaN正负Infinity数字类型的
2021-03-27 09:53:56
我不喜欢将大写与基元(如booleanand )一起使用number,以避免与对象包装器Booleanand混淆Number(但 ECMAScript 规范没有这样做)。此外,NaN也是原始值。
2021-04-03 09:53:56
我想强调的是,当使用对象方法对原始值进行处理时,变量只是暂时转换为对象,在建议的操作之后,对象将转换回原始值。这个概念可能会引起混淆,正如您在String 对象与文字中看到的那样- 修改原型?
2021-04-06 09:53:56

字符串和对象之间最重要的区别是对象必须遵循运算符的以下规则==

比较对象的表达式仅在操作数引用同一个对象时才为真。

因此,虽然字符串可以方便==地比较值,但当涉及到使任何其他不可变对象类型表现得像值类型时,你就不走运了。(也可能存在其他差异,但这是唯一让 JavaScript 开发人员每天都兴奋的差异)。例子:

"hello" == "hello"
-> true
new String("hello") == new String("hello") // beware!
-> false
这是错误的比较,这些显然是 2 个不同的对象,因此要比较字符串,您需要比较 new String("hello").valueOf()
2021-04-04 09:53:56