Объект окна Javascript, вызов функции из массива пространств имен

Пример кода: (Пожалуйста, не eval())

    var stringReference = "obj.inner.method";
    var namespace = stringReference.split(".");

    // Now I need to Call window[namespace].call();

Я немного смущен тем, как построить вызов функции. Конечный результат должен выглядеть так?

    window[obj][inner][method].call();

Контекст:

    <div data-attribute="click:obj.inner.method" > </div>

Я беру атрибут данных и привязываю слушателей событий на основе атрибута данных. Кроме того, заранее спасибо.


person Charlie    schedule 12.11.2013    source источник
comment
Это действительно звучит как ужасная идея, в чем причина этого?   -  person adeneo    schedule 13.11.2013
comment
иногда лучше объяснить цели, когда вы выходите из диких тангенсов... чем пытаться решить, как заставить работать абстрактный код   -  person charlietfl    schedule 13.11.2013
comment
Почему вы пытаетесь это сделать? Кажется довольно странным.   -  person Vivin Paliath    schedule 13.11.2013
comment
Мне нужно использовать это в файле шаблона. Когда компилятор создает шаблон, у меня есть функция привязки, которая проходит и связывает все прослушиватели событий. Затем удаляет атрибут данных. Я знаю, что есть миллион способов сделать что-то, поверьте мне, это то, что я должен сделать, учитывая существующую кодовую базу.   -  person Charlie    schedule 13.11.2013
comment
Что ж, вот как это сделать: › jsfiddle.net/xD7r7   -  person adeneo    schedule 13.11.2013


Ответы (4)


Попробуйте что-то вроде этого:

function getNamespace(base, path) {
    path = path.split('.');
    for (var i = 0; i < path.length; i++) {
        base = base[path[i]]
    }
    return base;
}

Используйте это как:

getNamepspace(window, 'obj.inner.method');
person sp0rkyd0rky    schedule 12.11.2013

Вы можете сделать рекурсивную функцию, например

function getProp(obj, keys) {
    if (keys.length) return getProp(obj[keys.shift()], keys);
    return obj;
}

А потом

getProp(window, 'document.body'.split('.')); // <body>

Цикл тоже будет работать, и в этом случае вы можете написать его как

function getProp(obj, keys) {
    var k;
    while (keys.length) k = keys.shift(), obj = obj[k];
    return obj;
}

Обратите внимание, что в этих примерах я использую shift, который имеет побочные эффекты.

person Paul S.    schedule 12.11.2013
comment
Какие побочные эффекты? - person leaf; 13.11.2013
comment
@wared arr = 'document.body'.split('.'); getProp(window, arr); arr; даст []. т. е. Array очищается. Я использовал shift, потому что это делает код коротким, и поэтому логика должна быть более наглядной, что то же самое. - person Paul S.; 13.11.2013
comment
Мне нравится выбор shift и while, которые позволяют избежать использования цикла for и его скучного i :), но на самом деле нет необходимости обращаться к массиву вне функции. - person leaf; 13.11.2013

Я предполагаю, что вы могли бы сделать что-то вроде этого:

var namespaces = stringReference.split(".");
var reference = window;
var i = 0;
do {
    reference = reference[namespaces[i]];
    i++;
} while(reference && i < namespaces.length);

if(reference) {
    reference.call();
}

Вы даже можете инкапсулировать внутри функции:

function getNamespacedObject(root, path) {
    var paths = path.split(".");
    var reference = root;

    var i = 0;
    do {
        reference = reference[namespaces[i]];
        i++;
    } while(reference && i < namespaces.length);

    return reference;
}

Затем вы можете вызвать это через var obj = getNamespacedObject(window, "my.namespaced.object");.

person Vivin Paliath    schedule 12.11.2013

Еще одно предложение, основанное на "sp0rkyd0rky" и "Paul S." те :

function fetch(base, path) {
    if (!path) { path = base; base = window; }
    path = path.split('.');
    while (path.length) base = base[path.shift()];
    return base;
}

Параметр base является необязательным и по умолчанию относится к window:

fetch(window, 'obj.inner.method') === fetch('obj.inner.method'); // true

Вы также можете взглянуть на этот ответ: https://stackoverflow.com/a/18892106/1636522. Однако есть много недостатков, которые вы должны учитывать (безопасность, производительность, ремонтопригодность, отладка...): https://stackoverflow.com/a/4599946/1636522.

person leaf    schedule 13.11.2013