Eşlenen fonksiyon olarak nesne yöntemlerini destekler javascript haritayı uygulamak?

1 Cevap php

Geçenlerde bir yöntem eklemek nesnelere uygulamak, sonra öğeleri bir grup oluşturmak için javascript Haritada bir uygulama kullanmaya çalıştı.

Öncelikle haritanın bir bataklık standart uygulama ile.

var map = function (fn, a)
{
    for (i = 0; i < a.length; i++)
    {
        a[i] = fn(a[i]);
    }
}

Kur.

var translateMenu = new Menu;

var languages = [ ['Chinese'   , 'zh-CN']
                , ['German'    , 'de']
                , ['French'    , 'fr']
                , ['Portugese' , 'pt']
                , ['Hindi'     , 'hi']
                ];

Ve benim işlevi ... (ana menüye için translateMenu eklerken anonim değil, daha sonra kullanılan gibi.)

var langItem = function (language, subMenu) 
    { 
       return new MenuItem(language[0], 'http://translate.google.com/translate?u=www.example.com&hl=en&ie=UTF-8&tl=en&sl=' + language[1] , "" , subMenu); 

    }

map ( langItem , languages );

Bu, tüm şimdi etrafında atmak için MenuItems bir dizi vardı, iyi çalıştı.

Trying to call map( Menu.add , languages ) would result in internal variables of Menu being undefined, and the call failing.
Now I'm certain this has to do with the scope of the Menu.add() method, so i thought if I passed in the object as well, it might work.

Ben nesneleri ve işlevleri kabul edecek yeni bir harita işlevi oluşturma çalıştı, ama aynı tanımlanmamış hata vardı.

objMap (fn , obj , a) {
    for (i = 0; i < a.length; i++)
    {
        obj.fn(a);
    }   
}
objMap ( add , translateMenu , languages );   // failed

Ben iyi çalışan bir dizi çekmek için addAll ile Menü () uzanan bu çalıştı ...

Menu.prototype.addAll = function (items){
    for (i = 0; i < items.length; i++)
    {
        this.add(items[i]);
    }
}

translateMenu.addAll( languages ); // yay! but I want a more elegant solution.

Her neyse, benim sorum, how could I implement map (or a similar generic function) to actually support using object methods as my mapped functions?.

1 Cevap

Haritayı aramaya çalışıyorum (Menu.add, dil)

İşte sorunun neredeyse kesinlikle bağımlı yöntemlerin JavaScript eksikliği olmasıdır.

Bir işlev için 'Bu' ayarı yöntemi nasıl elde edildiğini inceleyerek, sadece çağrı sırasında belirlenir. Eğer birini derseniz:

obj.method();
obj['method']();

JavaScript 'obj' için referans almak ve belirlenen yöntem çağrısı içinde 'bu obj =' olacaktır. Ama derseniz:

obj2.method= obj.method;
obj2.method();

Şimdi 'Bu' işlevi içinde nesne2 olacak, not obj!

Benzer şekilde, onun nesne yöntemi koparmak ve birinci sınıf bir nesne olarak bakın eğer:

var method= obj.method;
method();

Için hiçbir nesne olacak JavaScript küresel nesne (web tarayıcıları için aka 'pencere') olarak ayarlar yüzden 'Bu', ayarlanmış olsun. Bu durumda ne oluyor muhtemelen: 'Menu.add' yöntemi onun sahibi 'Menü' tüm referans kaybeder, bu yüzden geri çağırdı aldığında büyük olasılıkla bilmeden 'pencere' nesnesinin üyeleri yazma yerine bir menüsü.

Bu OO dil için elbette son derece sıradışı, ve neredeyse hiç ne istediğinizi, ama hey, bu nasıl JavaScript oynatıyor. Sessiz, sert-debug hatalara neden dilin mantığı parçasıdır.

Eğer harita işlevi için bir nesne başvurusu geçebileceği bu sorunu aşmanın, sonra doğru 'bu' başvuru ayarlamak için Function.call () / geçerli () kullanın:

function mapMethod(fn, obj, sequence) {
    for (var i= 0; i<sequence.length; i++)
        sequence[i]= fn.call(obj, sequence[i]);
}

mapMethod(Menu.add, Menu, languages)

Daha genel bir yolu kapatma kullanılarak elle işlev başvuruları bağlamak olacaktır:

function bindMethod(fn, obj) {
    return function() {
        fn.apply(obj, arguments)
    };
}

map(bindMethod(Menu.add, Menu), languages)

Bu yetenek JavaScript gelecekteki bir sürümüne içine inşa edilecek:

map(Menu.add.bind(Menu), languages)

Ve Function.prototype.bind yazarak güncel tarayıcıların bu tesis eklemek mümkün - gerçekten de, bazı JS çerçeveler zaten. Ancak dikkat:

  • ; ECMAScript 3.1 sözler de bindMethod biraz daha kod () Yukarıdaki gerektirir kısmi fonksiyonu uygulama yapmak) (bağlama içine ekstra argüman geçmek mümkün olacak

  • IE DOM olay işleyicileri gibi nesneleri üzerinde bağlanmış yöntemleri gibi başvurular bırakarak başladığınızda bellek sızdırıyor seviyor.