Как переопределить функциональность window.open?

Скажем, у меня есть window.open(без параметра имени), разбросанный по моему проекту, и я хочу изменить реализацию, чтобы везде, где имя не указано, я укажу имя по умолчанию.

То, что я хочу сделать, это привязать мой собственный метод к window.open, чтобы при каждом запуске window.open он внутренне вызывал мой собственный метод, который затем вызывает window.open(с параметром name).

Возможно ли это через Javascript? Будут ли возникать какие-либо проблемы с циклической зависимостью в этом, например, window.open, вызывающем мою пользовательскую функцию, которая в свою очередь снова вызывает функцию window.open?

P.s. Проще говоря, что я хочу сделать, это переопределить функциональность window.open.

Ответы

Ответ 1

Чтобы избежать циклических вызовов, вам нужно отбросить оригинальную функцию window.open в переменной.

Хорошим способом (который не загрязняет глобальное пространство имен) является использование закрытия. Передайте исходную функцию window.open анонимной функции в качестве аргумента (ниже open). Эта анонимная функция - это factory для вашей функции hook. Функция hook всегда привязана к исходной функции window.open с помощью аргумента open:

window.open = function (open) {
    return function (url, name, features) {
        // set name if missing here
        name = name || "default_window_name";
        return open.call(window, url, name, features);
    };
}(window.open);

Ответ 2

Я знаю, что этот ответ немного запоздал, но я чувствовал, что более общее решение может быть полезным для других людей (попытка переопределить другие методы)

function wrap(object, method, wrapper){
    var fn = object[method];

    return object[method] = function(){
        return wrapper.apply(this, [fn.bind(this)].concat(
            Array.prototype.slice.call(arguments)));
    };
};

//You may want to 'unwrap' the method later 
//(setting the method back to the original)
function unwrap(object, method, orginalFn){
    object[method] = orginalFn;
};

//Any globally scoped function is considered a 'method' of the window object 
//(If you are in the browser)
wrap(window, "open", function(orginalFn){
    var originalParams = Array.prototype.slice.call(arguments, 1);
    console.log('open is being overridden');
    //Perform some logic
    //Call the original window.open with the original params
    orginalFn.apply(undefined, originalParams); 
});

Ответ 3

P.s. Проще говоря, что я хочу сделать, это переопределить window.open функциональность.

var orgOpen = window.open;

window.open = function (url, windowName, windowFeatures) {
    alert("Overrided!"); 
    return orgOpen(url, windowName, windowFeatures); 
}

window.open("http://www.stackoverflow.com");