1

map数组对象的列表处理例程有时非常方便。这是使用它的便捷方法之一:

var numarr = [1,2,3,4];
console.log(numarr.map(String))

>>> ["1", "2", "3", "4"]

到目前为止,我认为这是理所当然的。然而,今天我对此感到困惑。上面的map函数返回的是一个字符串数组。我们通常将函数map作为参数传递给。在上述情况下,我们传递String对象。String是在Javascript实现里面实现的,所以不知道有什么特长。上面的代码就像为数组中的每个项目创建一个new实例一样。String

如果不清楚,请考虑这个。如果我决定用 Javascript say 实现一个对象MyString并将其传递给map,我将不会得到上述行为。

function MyString(x) { this.val = x; }

MyString.prototype.toString = function () { return String(this.val); };

var ms = new MyString(4)

console.log(String(ms));
>>> "4"

var arr = [1,2,3];
arr.map(MyString)
>>> [undefined, undefined, undefined]

有谁知道为什么 arr.map(String) 会这样工作?

更新:我在下面添加的评论更好地阐明了我的问题。

4

3 回答 3

4

Array.map返回一个数组,其元素是通过将指定函数应用于数组中的每个值而返回的值thisString是一个函数;它返回一个字符串。这里的所有都是它的。

于 2013-05-02T02:28:15.563 回答
3

在第二个片段的末尾,尝试console.log(val). 你会注意到你泄露了一个全局:

var arr = [1,2,3];
arr.map(MyString);
console.log(val); // "3"

使用时arr.map(MyString),您将该构造函数作为函数调用,而无需new创建实例。而且,既然什么都MyString没有return,你就会得到undefined结果。但是,您仍然设置了this.val, whilethis不是实例,而是全局对象

String不返回undefined,因为它有一个returnwhen没有调用new

当 String 作为函数而不是构造函数调用时,它会执行类型转换。

返回由 计算的字符串值(不是字符串对象)ToString(value)。如果未提供值,""则返回空字符串。

MyString您可以通过首先检查是否this是实例来模仿这一点,当this还不是实例时返回一个新实例:

function MyString(x) {
    if (this instanceof MyString) {
        this.val = x;
    } else {
        return new MyString(x);
    }
}

var arr = [1, 2, 3];
arr.map(MyString); // [ {val: "1"}, {val: "2"}, {val: "3"} ]
于 2013-05-02T02:38:17.707 回答
0

那是因为String 一个函数。它返回一个根据传递给它的内容构造的字符串。例如,如果您调用String(100),它将返回"100"

于 2013-05-02T02:27:55.133 回答