为什么新的Object(“foo”)返回“[object Object]”

时间:2011-03-11 19:54:11

标签: javascript arrays string type-conversion

Array.prototype.sort.call("foo"); // "[object Object]"
Array.prototype.sort.call(true); // true
Array.prototype.sort.call(1); // 1
Array.prototype.sort.call([1]); // [1]
Array.prototype.sort.call({}); // {}
Array.prototype.sort.call(function() {}); // function() {}

为什么对字符串调用数组方法的行为不同?我认为这是因为String还有.length[]元素访问者。

任何人都可以解释在错误类型上调用本机方法时究竟发生了什么?

[编辑]

Woops我解决了它。

new Object("foo"); // "[object Object]"

其余部分的行为相同。

让我们谈谈ES5规范:

  

15.2.1.1 Object([value])当使用no调用Object函数时   参数或一个参数值,   采取以下步骤:

     
      
  1. 如果value为null,未定义或未提供,则创建并返回一个新值   对象对象完全如同   标准的内置Object构造函数   被称为同样的人   参数(15.2.2.1)。

  2.   
  3. 返回ToObject(值)

  4.   

ToObject是:

  

9.9 ToObject抽象操作ToObject将其参数转换为a   Object的值类型   表14:

     

表14 - ToObject参数   输入结果

     

未定义扔一个   TypeError异常。

     

Null扔了一个   TypeError异常。

     

布尔创建一个   新的Boolean对象   [[PrimitiveValue]]内部属性   设置为参数的值。   有关布尔值的说明,请参见15.6   对象。

     

号码创建一个新号码   [[PrimitiveValue]]的对象   内部属性设置为   参数的价值。有关a,请参阅15.7   数字对象的描述。

     

的字符串   创建一个新的String对象   [[PrimitiveValue]]内部属性   设置为参数的值。   有关String的说明,请参见15.5   对象。对象结果是   输入参数(无转换)。

[恩惠]

现在为什么[[PrimitiveValue]]的{​​{1}}等于String

4 个答案:

答案 0 :(得分:1)

回答你的问题

  

现在为什么String的[[PrimitiveValue]]等于“[object Object]”?

您必须转到ECMAscript standard doc部分15.4.4.11

让obj成为调用ToObject传递此值作为参数的结果。

当你Array.prototype.call("abc")'这个'是字符串“abc”时。将该字符串传递给ToObject与调用new Object("abc")相同,这是隐式完成的。

此外,值得注意的是Array.prototype.sort.call("foo")在FF4中生成TypeError。

TypeError:Array.prototype.sort.call(“foo”)是只读的

这是因为需要(也在规范中)如果“ obj的任何数组索引属性,其名称是小于len的非负整数,则定义算法的数据属性 其[[Configurable]]属性为false。

使用[]访问器无法更改字符串。亲自试试

var test = "abc";
test[1] = 'x';
console.log(test) //'abc'

在遵循规范

时,FF4最有可能更加严格

答案 1 :(得分:1)

这里的'问题'是该类型的构造函数被调用(Number, String, Array, Boolean...),它们的行为与它们的“原始”对应物略有不同 - 它们返回一个包含原始值的对象。

以前规格中的[[PrimitiveValue]]或[[value]]是您可以通过.valueOf()访问的内部属性。

'foo' // is a string
String('foo') // is a string
new String('foo') // is a String object with [[value]] set to 'foo'

1 // is a number
Number(1) // is a number
new Number(1) // is a Number object with [[value]] set to 1

Object('foo') == (new String('foo'))
Object(1) == (new Number(1))

由于某种原因,webkit检查器似乎并不知道这些对象的原始值。因此,Object('foo')将打印'[object Object]',但如果您调用Object('foo').toString()或任何隐式调用toString或valueOf的方法(如alert(Object('foo'))),则会得到预期值“foo”

这也是原因:

var x = new Boolean(false);
// any object evaluates to true...
!!x // == true
Boolean(x) // == true

Javascript有很多奇怪的东西。还要考虑javascript引擎中有很多怪癖,并且对规范的遵从程度不同。

答案 2 :(得分:1)

[[PrimitiveValue]]的{​​{1}} String,如下所示:

[object Object]

代码中的问题是关键字console.log(String('foo'));

new

console.log(new String('foo')); 关键字将返回new的实例,其中包含您传递的任何类型构造函数的原型。

答案 3 :(得分:0)

我找到了解决方法。

function callArrayMethod(method, arg1, arg2) {
    if (arg2) {
        return Array.prototype[method].call(arg1.split(''), arg2).join('');
    }
    return Array.prototype[method].call(arg1.split(''), arg2).join('');
}

用法:

> callArrayMethod('sort', 'cba');
"abc"