Подтвердить что ты не робот

Что заменяет "на"?

Я знаю, что with предположительно является "плохой частью", но я никогда не заботился о нем, потому что я просто использовал его тщательно (так же, кстати, с операторами var в блоках). Теперь я понимаю, что with был изгнан из строгого режима EcmaScript 5.0.

Здесь мой прецедент: у меня есть библиотека, которая экспортирует около 20 или 30 функций. Большая часть моего кода никогда не использует какую-либо библиотеку, кроме тех частей, которые ее используют, много используют.

Сейчас мой код выглядит так:

with (mylib) {
    f1(f2(f1(), f3())); // five or 10 more lines like this
}

Чтобы быть совместимым, мне придется...

a) Переместите все функции в глобальную область (yuck).

b) mylib.f1(mylib.f2(mylib.f1(), mylib.f3())); (который является подробным)

c) var x = mylib; x.f1(x.f2(x.f1(), x.f3())); (который немного менее подробный, но менее значимый).

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

EDIT:

Что-то я должен был прояснить. Я не хочу, чтобы люди объясняли мне, почему я не хочу делать то, что я хочу делать; Я хочу, чтобы люди объясняли мне, как делать то, что я действительно хочу делать.

Дело в том, что по причинам, не зависящим от моего контроля, экспорт библиотеки имеет очень узнаваемые имена. Вместо того, чтобы называть их f1, f2 и т.д., Предположим, что они называются Bobs_Library_Function_F1, Bobs_Library_Function_F2 и т.д.

Мне просто не нужно много кода, который выглядит как

Bobs_Library.Bobs_Library_Function_F1(Bobs_Library.Bobs_Library_Function_F2(Bobs_Library.Bobs_Library_Function_F1(), Bobs_Library.Bobs_Library_Function_F3()));

(Настоящие имена не так уж плохи, они действительно красивы на самом деле, и префикс разрезает на это.)

Любой, кто серьезно не согласен с этим, ну, я надеюсь, вы никогда не будете использовать $.whatever, когда вы должны использовать jQuery.whatever, потому что это заставило бы вас выглядеть крупным лицемерным олетом.

Я думаю использовать $$.f1...

ДАЛЬНЕЙШЕЕ ИЗОБРАЖЕНИЕ

Серьезно, спасибо за все входные данные, но я не ищу опрос о том, лучше ли (a), (b) или (c). Я ищу выбор (d), который делает то, что with делает это хорошо.

Должен ли я, по крайней мере, вывести из строя режим блочного режима?

4b9b3361

Ответ 1

with плохо, потому что внутри блока вы понятия не имеете, откуда происходят переменные. Является ли f1 равным mylib.f1 или window.f1?

Я бы предложил перейти с опцией b). Вы можете использовать c), если хотите, это может помочь с длинными именами объектов, но b) - это путь.

EDIT. Еще одно предложение - использовать опцию a), но затем удалите ссылки из окна, когда закончите. Кроме того, будьте осторожны, чтобы не перезаписывать любые существующие свойства в window. Вы можете бросить их в другой объект для сохранения, если хотите. Основываясь на @Alex answer:

var bkupWin = {};  // Object to store existing window properties

for(var key in myLib) {
    if(myLib.hasOwnProperty(key)){
        if(window.hasOwnProperty(key)){
          bkupWin[key] = window[key];  // Backup current property
        }
        window[key] = myLib[key];  // Add property to window
    }
}

f1(f2(f1(), f3()));

for(var key in myLib){
    if(myLib.hasOwnProperty(key)){
        delete window[key]; // Remove property from window
        if(bkupWin.hasOwnProperty(key)){
          window[key] = bkupWin[key];  // Restore old property
        }
    }
}

Ответ 2

Согласно Mozilla:

Использование с не рекомендуется и запрещено в ECMAScript 5 строго Режим. Рекомендуемая альтернатива - назначить объект, чей свойства, к которым вы хотите получить доступ к временной переменной. Источник: https://developer.mozilla.org/en/JavaScript/Reference/Statements/with

Две вещи, которые нужно убрать:

  • Строгий режим - это единственное место, где это запрещено в ECMA5
  • Рекомендуемая альтернатива - это ваш вариант (c)

Единственная причина, по которой это не "значимо", как вы говорите, это выбор переменной типа x - наименее описательная вещь.

 mylib.f1(
      mylib.f2(
         mylib.f1(), 
         mylib.f3()
      )
 );

Является более читаемым и на самом деле занимает больше места, чем with. Если вы действительно хотите называть вызовы методов, возвращайте эти методы this:

var mylib = {
  f1: function () {
     /* do stuff */
     return this;
  },
  f2: function () {
    /* do stuff */
    return this;
  }
}

// then you can chain calls, organize with indentation
mylib
 .f1()
 .f2();

Ответ 3

Ни один из примеров не является вполне читаемым, я бы предпочел бы что-то вроде этого:

var 
    param1 = mylib.f1(),
    param2 = mylib.f3(),
    result = mylib.f2(param1, param2);
mylib.f1(result);

Конечно, имена переменных должны быть переименованы во что-то, что описывает их контент. Это создает много кода, но его читаемость и, что еще важнее, легче отлаживать. Чтобы его минимизировать, используйте специальные программы, которые даже могут каким-то образом оптимизировать код.

Ответ 4

Если все они применяются к тому же объекту, что и ваш пример, вы можете написать методы обертки, такие как

function f4() {
    return this.f1(this.f2(this.f1(), this.f3()));
}

и добавьте его в mylib. Таким образом, по крайней мере, уродство будет содержаться в вашем объекте.

Ответ 5

Возможно, вы могли бы сделать несколько функций фасада в своей библиотеке, что уменьшит некоторые из параметров опции b или c. Итак, это...

mylib.f1(mylib.f2(mylib.f1(), mylib.f3()));

Стал бы...

mylib.f123_facade();

Кроме этого, я думаю, вам просто придется мириться с беспорядком.

Ответ 6

Если библиотека не слишком навязчивая (перезаписывает что-либо), вы можете экспортировать всю библиотеку в глобальную область:

for (var key in myLib) {
    if (myLib.hasOwnProperty(key)) {
        window[key] = myLib[key];
    }
}

EDIT: Также вы должны быть осторожны, если библиотека использует this.

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

function doWith(func, myLib) {
    for (var key in myLib) {
        if (myLib.hasOwnProperty(key)) {
            this[key] = myLib[key];
        }
    }

    func.apply(this)
}

И пример:

var lib = {
    init: function(param1) {
        console.log(param1);
    },
    f2: function() {
        return "hi";
    }
};
doWith(function(){init(f2());},lib)

Посмотрите, как это работает: http://jsfiddle.net/msm595/AenUc/1/

EDIT3: NVM, Rocket является правильным OTL.