2012-06-08 3 views
4

Я хочу добавить возможность расширения объектов javascript путем добавления метода к прототипу.
Метод получит один или несколько других объектов и добавит все ключи/значения в this.
Это то, что я придумал:Расширение объектов Javascript с помощью CoffeeScript

Object::extend = (objects...) -> 
    @[key] = value for key, value of object for object in objects 

или это:

Object::extend = (objects...) -> 
    for object in objects 
     for key, value of object 
      @[key] = value 

Обе работы, как и ожидалось, и скомпилировать в то же яваскрипта код:

var __slice = [].slice; 

Object.prototype.extend = function() { 
    var key, object, objects, value, _i, _len, _results; 
    objects = 1 <= arguments.length ? __slice.call(arguments, 0) : []; 
    _results = []; 
    for (_i = 0, _len = objects.length; _i < _len; _i++) { 
    object = objects[_i]; 
    _results.push((function() { 
     var _results1; 
     _results1 = []; 
     for (key in object) { 
     value = object[key]; 
     _results1.push(this[key] = value); 
     } 
     return _results1; 
    }).call(this)); 
    } 
    return _results; 
}; 

Что я я не слишком доволен, это целая вещь результатов, созданная за цикл, который полностью избыточен для моей цели.
Есть ли способ, чтобы получить код больше как:

Object.prototype.extend = function() { 
    var key, object, objects, value, _i, _len; 
    objects = 1 <= arguments.length ? __slice.call(arguments, 0) : []; 
    for (_i = 0, _len = objects.length; _i < _len; _i++) { 
    object = objects[_i]; 
    (function() { 
     for (key in object) { 
     value = object[key]; 
     this[key] = value; 
     } 
    }).call(this); 
    } 
}; 

Спасибо.


Редактировать

Я знаю, что я могу просто embed Javascript код, но ищу решение CoffeeScript.

+0

Вы заметили тег 'coffeescript'? Код javascript является результатом компиляции coffeescript в javascript, я не писал этот js-код. –

+0

Только что заметил это и немедленно удалил мой комментарий ... Ой. – jahroy

+0

Yuck, изменяя 'Object.prototype' –

ответ

3

Вы можете попробовать добавить явные return:

Object::extend = (objects...) -> 
    for object in objects 
     for key, value of object 
      @[key] = value 
    return 

, который производит это:

var __slice = [].slice; 

Object.prototype.extend = function() { 
    var key, object, objects, value, _i, _len; 
    objects = 1 <= arguments.length ? __slice.call(arguments, 0) : []; 
    for (_i = 0, _len = objects.length; _i < _len; _i++) { 
    object = objects[_i]; 
    for (key in object) { 
     value = object[key]; 
     this[key] = value; 
    } 
    } 
}; 

функция Каждого CoffeeScript возвращает значение последнего выражения в функции, петли CoffeeScript также выражение. Это означает, что CoffeeScript должен собрать все то, что _results, чтобы получить возвращаемое значение для вашей функции, поскольку у вас был неявный return, применяемый к внешнему циклу. Если вы удалите этот неявный return, добавив явный «возврат ничего», тогда компилятор CS → JS кажется достаточно умным, чтобы не делать все, что было сделано дополнительно _results.

+0

Отлично! Это именно то, что я искал! Хотя я пошел с моей первой версией. Спасибо. –

+0

Лучше вернуться @ в конце, чтобы сделать возможной цепочку вызовов. – elisium

Смежные вопросы