簡體   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