2015-11-25 99 views
4

我最近看了一篇关于Object.prototype.valueOf() on MDN和感觉他们得到的东西完全错误的说:混淆方法Object.prototype.valueOf()

valueOf()方法返回指定的原始值目的。

我的意思是,这句话会做出一些意义,如果我们谈论这个方法的更具体的版本,例如String.prototype.valueOf(),这是在原型链更紧密,因此将被调用,而不是Object.prototype方法,当调用String对象的valueOf方法时。在这种情况下,将运行内部算法thisStringValue并且将返回对象的内部属性[[StringData]]的值,即基元串值。所以这实际上是从对象到原始值的转换。

但据我了解,中Object.prototypevalueOf方法的工作原理完全相反方式,通过调用内部方法ToObject

现在,如果Object.prototype.valueOf()是建立在普通的对象调用时,它将调用ToObject传入的方法中,它指向对象本身的该值,并且在这种情况下,ToObject将只返回在物体上的参考,通过toString()显示为[object Object]

假设我们将覆盖String.prototype.valueOf()的值,例如Object.prototype的相关方法,然后通过调用构造函数创建String对象。 - 如果我们现在调用valueOf(),我们将返回一个对象,而不是我们作为参数传入的原始字符串值。就我所见,Object.prototype.valueOf()中只有ToObject,没有从对象到原始值的转换。

所以我得到这个权利,他们是错的,还是我谁不明白它?

+0

有你那页的小黄***注上阅读***? –

+0

@ RokoC.Buljan只需将String.prototype.valueOf()替换为Number.prototype.valueOf()即可。它是同样的事情:如果通过调用具有参数5的构造函数创建一个Number对象并调用本地valueOf()方法,则会将数字5作为原始值。如果用Object.prototype.valueOf()覆盖Number方法,则会得到一个对象作为返回值。没有区别。 – SickBoy

+0

如果一个对象没有在原型链中覆盖这个方法,它的“原始值”就是对象本身。 – Barmar

回答

1

Object.prototype.valueOf的用途只是作为对象的默认方法,而不会用更具体的方法覆盖它。你不应该直接调用这个函数,当你调用一个对象的valueOf()方法时,它只是因为在原型链中没有更具体的东西而被调用。根据定义,如果一个对象没有覆盖它,它的“原始值”就是对象本身。

+1

这正是我认为这种方法的目的,完全确认!正因为如此,我认为将所有内置对象的valueOf方法作为一个对象是错误的,因为它们的作用方式不同,这是我在我的问题中链接的文章中所隐含的。如果可能的话,特定版本将转换为原始值,但“Object.prototype”的“默认”版本将永远不会这样做。所以,正如我看到的那样,说这个方法会“被调用来将一个对象转换为一个原始值”是错误的,正如在文章中所做的那样。 - 这才是重点。 ;-) – SickBoy

+1

我认为问题更多的是MDN的组织。它没有地方来记录通用协议,它只是记录特定的方法。但是系统如何使用这种方法的解释应该说明清楚。 – Barmar

2

valueOf()方法返回指定对象的原始值。

请记住,MDN是由像你和我这样的凡人写的。我不会选择这种方式来总结valueOf。更有意义的总结(借用下面的“说明”):

valueOf()方法返回当指定对象需要强制转换为原语时要使用的值。

对MDN页面的其余描述看起来相当合理和清晰。

从您的评论:

我认为这是错误地将内置对象的所有的valueOf的方法为一体,因为他们不采取同样的方式,这是我挂在文章中暗示在我的问题。

但文章本身说

每一个内置的核心对象覆盖此方法返回一个适当的值。

因此它是而不是把它们全部视为一体。是的,有一个valueOf接口,但它在不同的对象上有不同的实现。

这是错误的说法。这个方法应该“调用对象转换为原始值”

我没有看到文章中完全一致的短语,但它正确的声音,我。

0

该声明并不完全准确,并且对于特定实现而言,如您所说的那样“更真实”,但它是一个总结并解释了该方法的意图。

这是错误的说法。这个方法应该“称为一个对象转换为原始值”,

不,这是正确的。更确切地说:它被称为将对象转换为数字。从specs

当抽象操作OrdinaryToPrimitive被称为带有参数O和提示,采取以下步骤:

  1. 断言:类型(O)是对象

  2. 断言:类型(提示)是字符串,其值 是“字符串”或“数字”。

  3. 如果提示是“字符串”,则让方法名称为“toString”,“valueOf”»。

  4. 否则,让方法名称为 «“valueOf”,“toString”»。

  5. 对于在列表中的顺序每个方法名的名字,做

...

III。如果类型(结果)是而不是对象,则返回结果。

  1. 抛出TypeError异常。

没有保证,当然,那的valueOf的实现实际上返回原始值,但是这方法是什么。如果原型链中没有其他实现,则实际上将调用Object.prototype.valueOf将对象转换为原始值。正如你注意到的那样,它不起作用,但它仍然会被称为。

你可以自己尝试一下:

var myObject = { 
 
     valueOf: function() { 
 
     console.log('valueOf'); 
 
     return this; 
 
     }, 
 
     toString: function() { 
 
     console.log('toString'); 
 
     return this; 
 
     } 
 
    }; 
 
    
 
1 + myObject;

会打印:

valueOf 
toString 
Uncaught TypeError: Cannot convert object to primitive value