2013-05-02 55 views
1

数组对象上的列表处理例程map有时非常方便。这里有一个方便的使用方法:在Javascript中,为什么array.map(String)返回字符串数组?

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

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

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

如果不明确,请考虑这一点。如果我决定用Javascript实现一个对象,说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(字符串)工作的方式呢?

更新:A comment I added below更好地阐明了我的问题。

+4

你看到什么'typeof运算String'回报? *“如果我决定在Javascript中实现一个对象,说'MyString' [[]]”*:'MyString'也是一个函数!但它显示“未定义”,因为你没有返回任何形式。 – 2013-05-02 02:38:26

+0

你说得对,我什么都没有回来。但是,我应该返回什么?一个“MyString”的新实例? – Jayesh 2013-05-02 13:34:00

+0

这里重要的一点是,虽然'String'是一个construtor函数,它在用'new'调用时返回一个字符串* object *,当它被调用*时不返回*'new',它会返回一个字符串*原始值*。如果你愿意,你可以用你的功能做类似的事情。但是通常这对自定义构造函数没有意义,所以你更愿意使用带'arr.map('function(v){return new MyString(v);});''的'.map'。 – 2013-05-02 13:41:13

回答

2

在第二个片段结尾处,请尝试console.log(val)。你会发现你已经泄露一个全球性的:

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

使用arr.map(MyString),你调用一个构造函数的函数,而new创建实例。而且,由于MyString没有return任何内容,因此您在结果中获得undefined。但是,您仍然设置this.val,而this不是实例,而是全局对象

String没有返回undefined,因为它有一个returncalled without new

当字符串被称为函数,而不是作为一个构造函数,它执行一个类型转换。

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

您可以通过检查this是一个实例首先,返回一个新的实例时this不是一个已经模仿这与MyString

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"} ] 
+0

关于泄露“val”的好观察。花了我一段时间才明白。但答案并没有解决我的问题。查看我添加的更新。我不是在寻找一个实用的解决方案,只是想更好地理解Javascript。 – Jayesh 2013-05-02 15:27:38

+0

@Jayesh关于[你的评论](http://stackoverflow.com/q/16329393/#comment23403334_16329420),你可以通过'if(this instanceof ...)'来避免无限递归。有了它,你可以在它是一个实例时修改'this',或者当它不是时返回新的MyString(x)''。如果需要,它应该只缓冲一次。我用一个例子更新了我的答案。 – 2013-05-02 17:51:18

0

那是因为String的一个函数。它返回一个由传递给它的字符串构成的字符串。例如,如果您致电String(100),它将返回"100"

3

Array.map返回一个数组,其数组元素是通过将指定函数应用于this数组中的每个值而返回的值。 String is a function; it returns a string.这就是它的全部。

+0

函数总是一流的Javascript对象:一个函数是一个函数对象。您也可以在其他javascript“类型”上运行相同的技巧:Array,Date,Number,Boolean,Object。 – thefrontender 2013-05-02 02:37:08

+0

@thefrontender:你的观点是什么? (作为这个答案的评论) – 2013-05-02 02:42:14

+0

@FelixKling当我评论时,这是最好的答案。调查者显然对JS中的对象和函数之间的关系感到困惑。你认为这个评论是否属于其他地方或者没有帮助? – thefrontender 2013-05-02 02:47:13

相关问题