2017-01-15 11 views
0

При использовании шаблона модуля в ES5 вызов this.methodName дает мне методName в возвращаемом объекте. Но в ES6 это немного отличается в настоящее время ....Как получить доступ к «общедоступной» функции в возвращаемом объекте (шаблон модуля) с ES6?

старый путь (с ES5):

var moduleOld = (function() { 
    //private 
    var privateArray = [1,2,3,4]; 

    return { 
     getItemCount: function() { 
     return privateArray.length; 
     }, 

     getTotal: function() { 
     return this.getItemCount(); 
     } 
    }; 
    })(); 

    //output 
    console.log(moduleOld.getTotal()); //4 <-- Now, I want the same results with ES6 syntax 

Новый способ (с ES6):

let moduleES6 = (()=> { 
    //private 
    let privateArray = [1,2,3,4]; 

    return { 
     getItemCount:()=> { 
     return privateArray.length; 
     }, 

     getTotal:()=> { 
     return this.getItemCount(); 
     } 
    }; 
    })(); 

    //output 
    console.log("es6 ", moduleES6.getTotal()); //Uncaught TypeError: this.getItemCount is not a function 

Там способы вокруг него ...

let moduleES6_2 = (()=> { 
    //private 
    let privateArray = [1,2,3,4]; 

    return { 
     getItemCount:()=> { 
     return privateArray.length; 
     }, 

     getTotal:()=> { 
     return moduleES6_2.getItemCount(); // I changed "this" to the module name, i.e. moduleES6_2 
     } 
    }; 
    })(); 

    //output 
    console.log("es6 calling by module name: ", moduleES6_2.getTotal()); //works! But what if I change the module's name? Then I have to also change the function call in the getTotal function. 

Таким образом, изменение имени модуля не должно быть много вопрос:

let moduleES6_3 = (()=> { 
    //private 
    let privateArray = [1,2,3,4]; 
    function getItemCount() { 
     return privateArray.length; 
    } 
    return { 
     //getItemCount: getItemCount, 
     getTotal:()=> { 
     return getItemCount(); // I am calling the private method. Not the public method! 
     } 
    }; 
    })(); 

    //output 
    console.log("es6 by private method: ", moduleES6_3.getTotal()); //works! But I don't really use the method in the return object, but rather the private declared method. 

Как получить доступ к «общедоступной» функции в обратном объекте (шаблон модуля) с ES6?

let moduleES6 = (()=> { 
    //private 
    let privateArray = [1,2,3,4]; 
    function getItemCount() { 
     return privateArray.length; 
    } 
    return { 
     getItemCount:()=> { 
     return privateArray.length; 
     }, 
     getTotal:()=> { 
     return this.getItemCount();//<-- how to access the public getItemCount method? 
     } 
    }; 
    })(); 
+1

В модулях ES6 является частью языка ('import',' export' и друзья), так что нет никакой необходимости хаки, такие как «шаблон модуля». – georg

+0

@georg AFAIK импорт и экспорт не поддерживаются всеми браузерами. Просто попробовал его с Chrome 53.0.2785.143 (64-разрядный) – thadeuszlay

+0

_ «Новый способ (с ES6)» _ Это не новый способ, это по-другому. Функции стрелок как методы редко имеют смысл. – zeroflagL

ответ

0

Вы можете использовать сокращенный синтаксис для методов объекта как getItemCount():

let moduleES6 = (()=> { 
    //private 
    let privateArray = [1,2,3,4]; 

    return { 
    getItemCount() { 
     return privateArray.length; 
    }, 

    getTotal() { 
     return this.getItemCount(); 
    } 
    }; 
})(); 

moduleES6.getTotal() //4 
+0

Извините, что я не могу дважды проверить следующее, потому что я действительно занят поиском чего-то еще: я подозреваю, что проблема заключается в использовании функций стрелок, которые влияют на «этот» указатель. Поэтому, чтобы исправить это, вы либо используете стиль декларации функции() {...}, либо используете подход hackerdave. (Я лично использовал подход хакердава.) –

+0

@MarkBirbeck 'getTotal() {' в объектном литерале является ярлыком для 'getTotal: function ....'. Это необходимо для правильного «этого». Ответ правильный, хотя предпочтительным является подход модуля ES6. – estus