[英]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.