繁体   English   中英

将构造函数传递给 Array.map?

[英]Passing a constructor to Array.map?

我该怎么做这样的事情:

var a = [1,2,3,4];
a.map(Date.constructor);

此代码在 Google V8 上引发错误:

SyntaxError: Unexpected number

我也试过:

a.map(Date.constructor, Date.prototype)

结果相同。

我认为 OP 正在寻找的内容与此严格相似:

var nums = [1, 2, 3];
var strs = nums.map(String);
//=> ['1', '2', '3']; // array of strings

我认为原因是这非常优雅,无论是在像上面这样的简单类型转换操作中,还是在更有趣的任务中,比如将某物的一种表示转换为不同的表示,如下所示:

function MyCoolObject(oldObject) {
    // generates new object by consuming old one
    // maybe attach some cool class methods via prototype
    return this;
}

var newList = oldList.map(MyCoolObj);
//=> array of MyCoolObj based on oldObject

问题似乎在于,通过将构造函数传递给Array.map创建新的 object 时,它是window的扩展版本; 也就是说,构造函数中的this指的是全局 scope,这很糟糕,因为(1)在window上挂道具不是您的目标,并且(2)您以这种方式创建的对象不是唯一的实例。

就其价值而言,最初的类型转换示例也不是它的全部内容,因为:

strs[0] instanceof String
//=> false // UGH!

到目前为止,我提出的唯一解决方案需要以不同的方式编写构造函数——这显然不能用于Date之类的本机类型:

function Human(animal) {
    var h = new Object();
    h.species = 'human';
    h.name = animal.name;
    return h;
}

var humans = animals.map(Human);

通过将返回值定义为新的 object,我们切断了全局 scope 和this之间的连接; 至少,这就是我认为这里发生的事情。 (您也可以返回 JSON 文字,而不是调用Object 。)

如果我希望这些对象有一个有趣的原型,我必须单独定义它,然后显式附加它:

// this object will be used as the prototype for new Human instances
var HumanProto = {
    species: 'human',
    speak: function() { console.log('My name is ' + this.name); },
    canDrink: function() { return this.age >= 21; }
}

// then, in Human, make this change
var h = new Object(HumanProto);

在这种情况下,返回 JSON 并没有那么好,因为似乎没有任何有效的方法来设置对象文字的原型; 即使可以,您也永远不希望是真的:

myObject.hasOwnProperty('prototype');
//=> true // only if myObject = { prototype: HumanProto }

我认为确保新 object 具有所需原型的最佳方法是将可能的原型作为参数传递给new Object()

这种模式理想吗? 我不知道。 这似乎有点奇怪,因为现在有两个符号与创建人类相关: Human是构造函数 function,而HumanProto是显式原型。 更重要的是,如果您已经拥有了一个有趣的自定义类的生态系统,而这些类并不是为了与这种模式兼容而编写的,那么这似乎是一个真正的障碍。

那里可能有更好的方法。 也许有人会发布它。

这是你想要做的吗?

var a = [1, 2, 3, 4];
a.map(function(obj) { return new Date(obj); });

map 方法只是使用提供的回调 function 迭代一个数组(https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/map)。 所以:

var a = [1,2,3,4];
a.map(function(b) { return b+10; }); // [11, 12, 13, 14]

你想从中得到什么:

Date.constructor(1);
Date.constructor(2);
Date.constructor(3);

从评论更新:

这里的问题是通过将 Date object 构造函数传递给 map function 来创建具有来自数组 a 的时间值的 Date 对象数组。 无论如何,代码中有一个错误(请参阅对 pst 的评论) - 设置

我明白了,就像:

var a = [1,2,3,4];
a.map(Date.prototype.constructor);

Date 是 function,因此 Date.constructor 是 function 的构造函数。 Date object 构造函数的正确调用如下所示:

Date.prototype.constructor();

要不就:

Date();

这里的问题是使用数组a时间值创建一个 Date 对象数组,但是在没有new运算符 (ECMA-262 15.9.2) 的情况下,无法调用 Date object 构造函数并将 arguments 传递给它

但是任何 object 构造函数都可以作为函数调用,其结果与我使用new运算符相同(例如,错误 object 构造函数(ECMA-262 15.11.1))。

$ var a = ['foo','bar','baz'];
$ a.map(Error);
> [ { stack: [Getter/Setter], arguments: undefined, type: undefined, message: 'foo' },
    { stack: [Getter/Setter], arguments: undefined, type: undefined, message: 'bar' },
    { stack: [Getter/Setter], arguments: undefined, type: undefined, message: 'baz' } ]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM