Вопрос по internet-explorer, javascript – Удаление свойства окна в IE

62

Я не могу найти никакой информации по этому вопросу; почему следующий код не работает в IE?

window.x = 45;
delete window.x;
// or delete window['x'];

IE сообщает, что «объект не поддерживает это действие» ошибка. Имеет ли это какое-либо отношение к этой итерации по свойствам окна в проблеме IE?

И просто чтобы быть ясным, потому что это не похоже на то, что кто-то на самом деле сказал это в любом из ответов: Этоbug в Internet Explorer. В спецификации 1999 года (3-е издание) нет ничего, что позволяло бы исключение изdelete, даже если свойство не существует или не может быть удаленоwindow.x в любом случае не должно быть), а новая спецификация 5-го издания допускает только исключения, выбрасываемые изdelete в новом строгом режиме. В этом нет ничего особенногоwindow в этой связи. И еще, движок JScript в IE8still показывает эту ошибку, в 2010 году.sigh T.J. Crowder
Good relevant article. alex
T.J. Crowder, window - это не объект, а средство доступа к корневому пространству имен. Он не имеет свойств как таковых, поэтому при запуске удаления для него, например, в этом случае, он не обязан фактически удалять их по любой причине. Установка неопределенного в имени объекта является приемлемой, потому что gc будет проходить и устранять объекты, на которые нет ссылок. Надеюсь, что это поможет понять реальную проблему здесь и почему это не столько ошибка, сколько плохой выбор реализации для языка, который медленно обновляется для модернизации Jeffrey Gilbert

Ваш Ответ

4   ответа
2

Это помогает?

window.x = 45;
alert(window.x);
window.x = null;

Я попробовал это в IE, и у window.x было значение, которое доказывает, что его можно установить. Установка значения на ноль - ваш лучший выбор для его очистки.

К сожалению, это не удаляет переменную из памяти, оно просто дает ей нулевое значение, но это единственный вариант, насколько я могу судить.
Благодарю. Я пошел дальше и использовал window.x = undefined. Это все еще не то, что я хочу, но это сделаю. Странно, что я не нашел в Интернете никакой полезной информации по этому поводу. gasper_k
49

Гаспер прокомментировал решение, которое он закончил, но я думаю, что стоит назвать реальный ответ:

try 
{ 
    delete window.x; 
} 
catch(e) 
{ 
    window["x"] = undefined; 
}

Интересная проблема, я просто ударился головой об этом сегодня вечером. Исключение выдается в IE, но не в Firefox. Я подозреваю, что это обходной путь утечки памяти, поэтому используйте экономно.

Был задан вопрос, почему бы просто не назначить неопределенное? Имеет значение, если вы хотите перечислить ключи позже (хотя, если вы полагаетесь на обходной путь, перечисление ключей по-прежнему не будет выполнять то, что вы хотите ...). Но в любом случае, чтобы подчеркнуть разницу между удалением и просто назначением неопределенного (http://jsfiddle.net/fschwiet/T4akL/):

var deleted = {
    a: 1
};

var cleared = {
    a: 1
};

delete deleted["a"];
cleared["a"] = undefined;

for(var key in deleted) {
    console.log("deleted has key", key);
}

for(var key in cleared) {
    console.log("cleared has key", key);
}

console.log("deleted has a?", deleted.hasOwnProperty('a'));
console.log("cleared has a?", cleared.hasOwnProperty('a'));

производит вывод:

cleared has key a
deleted has a? false
cleared has a? true 
Когда я показал им это решение, коллега задал хороший вопрос: почему бы не пропустить посредника и заменить вызов удаления неопределенным назначением?
Хороший вопрос, мне потребовался год, чтобы столкнуться с ситуацией, когда разница имеет значение.
36

Я бы сделал это так:

    window[x] = undefined;
    try{
        delete window[x];
    }catch(e){}
спасибо, это то, что я сделал в конце. Он генерирует исключение в IE, но он перехватывается и не наносит ущерба. gasper_k
Наиболее подробное объяснение удаления, которое я видел, находится здесь, это раздел IE. (Если кто-то придет к этому с более сложной проблемой в будущем)perfectionkills.com/understanding-delete/#ie_bugs
1

Я реализовал это решение, когда имел дело с кэшированием моих собственных данных - данные были не настолько частыми, чтобы частота кеша была такой, чтобы утечка памяти могла стать проблемой. Это дорого, но периодически переотображать объект было для меня самым простым способом быть уверенным, что он не выйдет из-под контроля.

obj = {a: 1, b: 2, c: 3};
var max;

function unset(obj, key) {
    try {
        delete obj[key];
    } catch (e) {
        obj[key] = undefined;
    }

    max++;

    if(max > 200) {
        var keys = Object.keys(obj);
        var len = keys.length;
        var n_obj = {};
        for(var i = 0; i < len; i++) {
            if(obj.hasOwnProperty(keys[i]) && obj[keys[i]] !== undefined) {
                n_obj[keys[i]] = obj[keys[i]];
            }
        }
        return n_obj;
    }
    return obj;
}

obj; //{a: 1, b: 2, c: 3}
obj = unset(obj, "b"); //{a: 1, b: undefined, c: 3} OR {a: 1, c: 3}
//and then eventually we'll garbage collect and...
obj = unset(obj, "b"); //{a: 1, c: 3}   

Надеюсь, это полезно для некоторых!

это было бы это! пересмотрено.
Object.keys() не будет работать в & lt; = IE8 (которые вызывают проблемы сdelete на первом месте). Кроме того, вы, вероятно, имели в видуobj[key] = undefined внутри блока захвата. ;]

Похожие вопросы