Что заменяет "на"?
Я знаю, что 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
делает это хорошо.
Должен ли я, по крайней мере, вывести из строя режим блочного режима?
Ответы
Ответ 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.