як розширити метод у javascript?

Я хочу додати додаткові функції до методу, наприклад:

console.log()

тому оригінальна функція "log" зберігається, і я можу отримати це, щоб зробити щось нове. Чи це можливо? Я прочитав кілька бітів про використання прототипу, але це не зовсім зрозуміло.

Дуже дякую,

3
fcombine дозволяє комбінувати функції та повертає нові.
додано Автор Raynos, джерело
Подумайте про це так: ви можете ADD something to OBJECT, але не можете змінити те, що вже існує. Ви можете додати log2() для консолі об'єкта, але не може змінити вже існуючий журнал ().
додано Автор friendzis, джерело

5 Відповіді

Це дуже просто. Якщо ви хочете, щоб новий log mehod замість старого методу log , виконайте щось подібне:

console._log = console.log;//just backing up old log method
console.log = function(){
    console._log(arguments);
    alert("I'm doing something else here");     
}
console.log(console);

UPDATE:

Всі запропоновані рішення, включаючи шахту, не відтворювали поведінку журналу відмінно, як зазначив @TomBates. Вихід відрізнявся тому, що аргументи записуються в об'єкт, замість того, щоб проходити окремо. Єдиний спосіб, який я міг би знайти для відтворення поведінки старого журналу + розширення функціональності, було таким:

    console.log(window, this, console);//old log in action

console._log = console.log;//just backing up old log method
console.log = function(){
    var args_string = '';
    for(i in arguments){
        if(arguments.hasOwnProperty(i)){
            args_string += 'arguments['+ i + ']';
            if(i != arguments.length - 1){
                args_string += ',';
            } 
        }
    }
    var expression = 'console._log(' + args_string + ');';
    eval(expression);

    alert("I'm doing something else here"); 
   //your dazzling method extension here   
}

console.log(window, this, console); //new log in action

Не такий елегантний, але працює як очікується. виходи старого журналу та нового журналу тепер ідентичні.

2
додано
Ви просто зламали console.log.length
додано Автор Raynos, джерело
Занадто багато апострофів. :)
додано Автор freakish, джерело
виправлено, додано аргумент до нового консольного методу, тому він стає таким же корисним, як "старий"
додано Автор marcio, джерело
це правда, не знали про це. Виправлено, дякую.
додано Автор marcio, джерело
Я думаю, консоль.log.length необхідно бути недоторканим для деяких тестових костюмів, щоб працювати, як очікувалося, тому, здається, важливо залишити його так, як це було, як це було вдало, @Deeptechtons також у своїй відповіді.
додано Автор marcio, джерело
Так, це відбувається тому, що об'єкт аргументів обертає аргументи функції і це перешкоджає виходу журналу. Погляньте на оновлену відповідь, маєте нове краще рішення (менш елегантне).
додано Автор marcio, джерело
Дякую за всі відповіді. @marcioAlmada: це рішення практично працює, хоча оригінальна поведінка інша. Наприклад, якщо ви вводите елемент jQuery до/після використання цього рішення, ви побачите різницю в поведінці журналу. (Або Firebug, або веб-інспектор на Webkit)
додано Автор Tom Bates, джерело

Якщо ви суворо намагаєтесь розширити консоль в Firebug, вона не має прототипу, так що вам буде добре це зробити

console.logMe = function(){console.log(arguments)};
console.logMe("welcome to SO");

Оновити

Оскільки я зрозумів це питання неправильно, я хотів би це виправити. ОП хотів абстрагувати базовий метод і переопределити базовий метод. (Схоже, я кажу про сміття, див. Код нижче)

function myConsole() {}

myConsole.prototype = {
    _log: console.log,
    Log: function() {
        this._log(arguments)
    }
};

з усіма іншими способами вам доведеться це робити знову і знову. Але тут кожен примірник, який ви створюєте, матиме розширений метод і власну вбудовану реалізацію.

Використання

var x = new myConsole();
x.Log("Hi this is Deeptechtons");
1
додано
@ OptimusCrime див. Оновлений варіант відповіді
додано Автор Deeptechtons, джерело
@ marcioAlmada переглянути оновлений відповідь
додано Автор Deeptechtons, джерело
@ Кожен, хто знищив, було б непогано знати причину зниження.
додано Автор Deeptechtons, джерело
Я зрівняв його, але с% його, ваш код добре, і я оцінив це неправильно! (виглядав дуже швидко, і думав, що така сама помилка мала ще одну відповідь). Намагався скасувати голосування, але програма повідомляє, що не можу скасувати мій downvote, якщо відповідь не буде відредагована (пройшло дуже багато часу). Не могли б ви внести незначну редакцію, щоб я міг відмінити мій downvote ?? Мені дуже шкода.
додано Автор marcio, джерело
добре, внизу понизити :)
додано Автор marcio, джерело
Чи не я, але питання полягало у розширенні методу, а не на створенні нового.
додано Автор OptimusCrime, джерело

оскільки яваскрипт орієнтований на виклики, ви можете зробити це:

console._log_without_my_extension = console.log
console.log = function() { console._log_without_my_extension(); .... }

наприклад.

1
додано
ваш console._log_without_my_extension() має отримати параметр, який все ще буде корисним.
додано Автор marcio, джерело
так, звичайно, він повинен отримувати і переносити будь-які параметри, які йому потрібні!
додано Автор Marian Theisen, джерело

Ви можете використовувати властивість prototype лише тоді, коли у них є об'єкти. console не є одним з них. Використовуйте інші відповіді для цього. І прочитайте це, щоб дізнатися про протокол :

http://phrogz.net/js/classes/ExtendingJavaScriptObjectsAndClasses.html

До речі: неможливо продовжити функції, якщо ви не зробите обгортку, так само, як запропоновано в інших відповідях.

0
додано

Розширення в JS не є функцією за замовчуванням, наскільки я знаю, єдиний спосіб є щось на зразок наступного:

var oldLog = console.log;
console.log = function(){
    //doStuff
    oldLog(arguments);
    //doStuff
}
0
додано
ІТ КПІ - JavaScript
ІТ КПІ - JavaScript
504 учасників

співтовариство javascript розробників в Telegram