Методы нативного объекта карты Javascript - PullRequest
3 голосов
/ 12 ноября 2010

В Python вы можете что-то вроде этого:

>>> list(map(str.upper, ['foo','bar']))
['FOO', 'BAR']

Я хотел бы иметь возможность сделать что-то подобное в JavaScript:

Я попробовал следующее в Chrome с использованием собственной карты (https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/map):

['foo','bar'].map(String.prototype.toUpperCase)

['foo','bar'].map(String.prototype.toUpperCase.call)

Почему не работает? Есть какой-нибудь элегантный способ сделать это, или я должен обернуть toUpperCase в функцию обратного вызова? Thx

Ответы [ 5 ]

2 голосов
/ 10 ноября 2012

Попробуйте:

['foo','bar'].map(Function.prototype.call.bind(String.prototype.toUpperCase))

или для того же эффекта:

['foo','bar'].map(Function.call.bind("".toUpperCase))

Обработка JavaScript this - плохая поездка.

1 голос
/ 15 декабря 2013

Вы все упускаете суть. : -)

Мы хотим вызвать метод (не функцию) для всех элементов массива. Вы можете использовать map:

a.map(function(x){x.frob()})

но это слишком много печатать. Мы хотим сказать:

a.mapm(A.frob)

где A - это класс элементов a, а mapm - это новый метод Array, который вызывает свой метод аргумента для каждого элемента this (в данном случае массив a). Вы можете определить mapm так:

Array.prototype.mapm = function (method)
{
    return this.map(function (x) { return method.apply(x) } )
};

и назовите его так:

["a", "b", "c"].mapm("".toUpperCase)    ==>     ["A", "B", "C"]

Единственная проблема заключается в том, что вы добавили новый элемент mapm в каждый массив, хотя он игнорируется большинством Array методов, например, length и map.

1 голос
/ 12 ноября 2010

Современные браузеры поддерживают это (, хотя это последнее добавление )

var a = ['foo','bar'];
var b = a.map(String.toUpperCase);

alert(b[1]);

или даже

var a = ['foo','bar'].map(String.toUpperCase);
alert(a[0]);

пример: http://www.jsfiddle.net/xPsba/

1 голос
/ 12 ноября 2010

Это потому, что String.prototype.toUpperCase работает на this (Context) объекте, но функция map не может установить элемент массива как контекст Это передает это как аргумент. Обходной путь будет

['foo','bar'].map(function(k) { return String.prototype.toUpperCase.call(k) });
0 голосов
/ 12 ноября 2010

Вы можете использовать что-то вроде этого:

function map(arr, fn){
    var i = 0, len = arr.length, ret = [];
    while(i < len){
        ret[i] = fn(arr[i++]);
    }
    return ret;
}

И использовать это:

var result = map(['foo', 'bar'], function(item) {
    return item.toUpperCase();
});

console.log ( result ); // => ['FOO', 'BAR']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...