我认为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
,是一个扩展版本window
;那是,this
构造函数内指的是全局范围,这很糟糕,因为 (1) 挂起 props 不是你的目标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);
通过将返回值定义为一个新对象,我们切断了全局范围和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 并不好,因为似乎没有任何有效的方法来设置对象文字的原型;即使你可以,你也永远不会想要this是真实的:
myObject.hasOwnProperty('prototype');
//=> true // only if myObject = { prototype: HumanProto }
我认为确保新对象具有所需原型的最佳方法是将潜在原型作为参数传递给new Object()
.
这种模式理想吗?我不知道。这看起来有点奇怪,因为现在有两个与创造人类相关的符号:Human
构造函数,以及HumanProto
显式原型。更重要的是,如果您已经拥有一个有趣的自定义类生态系统,而这些自定义类的编写方式并非与此模式兼容,那么这似乎是一个真正的障碍。
也许有更好的出路。也许有人会发布它。