This question already has answers here:
Object.prototype.valueOf() method

(2个答案)


7年前关闭。



({}).valueOf.call(myvar)是做什么的?



我的问题是怎么做?有人可以给一个更长的答案吗?这是如何在幕后完成的。因为valueOf()方法旨在返回原始值而不是object。
console.log{name:"sameer"}.valueOf() //returns an object but cant be displayed since toString() method will be called by js so [object Object] gets displayed which is a string ,how to display the exact return value from valueOf() method .Is there a way?

最佳答案

您好again!我们再次面对强大的对手。在开始之前,让我们消除一个错误的想法:



不准确。如果将原始值传递给它,则valueOf返回一个对象。如果执行valueOf(object),则会得到相同的对象:valueOf(object) === object。您可以轻松地看到:

var obj = {};
obj.valueOf() === obj; //true

现在,对于一个更有趣的问题:如何定义valueOf?让我们看一下ES5规范以及v8和Spidermonkey源码。
valueOf(specv8spidermonkey):
function ObjectValueOf() {
  return ToObject(this);
}

如我们所见,它只是返回规范中定义的ToObject。兔子洞出现了。
ToObject(specv8spidermonkey)
function ToObject(x) {
  if (IS_STRING(x)) return new $String(x);
  if (IS_SYMBOL(x)) return new $Symbol(x);
  if (IS_NUMBER(x)) return new $Number(x);
  if (IS_BOOLEAN(x)) return new $Boolean(x);
  if (IS_NULL_OR_UNDEFINED(x) && !IS_UNDETECTABLE(x)) {
    throw %MakeTypeError('null_to_object', []);
  }
  return x;
}

头奖我们可以在这里看到整个流程。如果它是字符串,数字, bool(boolean) 值等,则返回包装器($String$Boolean等,其代表实际的String或Number;请参见here);如果参数无效,则抛出错误;否则,返回参数。

那只蜘蛛猴的来源在兔子洞的深处。它这样定义ToObject:
JS_ALWAYS_INLINE JSObject *
ToObject(JSContext *cx, HandleValue vp)
{
    if (vp.isObject())
        return &vp.toObject();
    return ToObjectSlow(cx, vp, false);
}

因此,如果不是对象,请调用ToObjectSlow。扣上爱丽丝,就会有C++。我们需要看看 ToObejctSlow 的作用:
JSObject *
js::ToObjectSlow(JSContext *cx, HandleValue val, bool reportScanStack)
{
    if (val.isNullOrUndefined()) {
        ...error throwing magic here...
        return NULL;
    }

    return PrimitiveToObject(cx, val);
}

查看参数为null还是未定义后,将进行更多间接操作。结局是here:
JSObject *
PrimitiveToObject(JSContext *cx, const Value &v)
{
    if (v.isString()) {
        Rooted<JSString*> str(cx, v.toString());
        return StringObject::create(cx, str);
    }
    if (v.isNumber())
        return NumberObject::create(cx, v.toNumber());

    JS_ASSERT(v.isBoolean());
    return BooleanObject::create(cx, v.toBoolean());
}

与v8版本几乎相同,只是分类法不同。

现在,正如我之前所说,我认为您的问题更多地与代表看到的对象有关。 Firebug和chrome的devtools更适合显示对象。但是,如果尝试对其进行alert编码,则会看到不幸的[object Object],因为那是({}).toString()给您的内容(因为它再次给出了[object InternalClassName]形式的字符串,就像我们之前所见)。

作为奖励,请尝试console.dir({foo : 'bar'})

08-06 03:22
查看更多