Комментарии 26
Как по мне, так
существенный недостатокwith({}) { var x = "abc"; } console.log(x) // 'abc'
with({}) { var this.x = "abc"; }
console.log(x); // undefined
чуете где подвох?
var this.x = "abc";
Вот тут действительно есть подвох. Это невалидное выражение.
Если же речь таки шла о
with({}) { this.x = "abc"; }
console.log(x);
То будет возвращен «abc»
Понял, но всё равно у меня
Chromium 11
х = 123
123
with ({}) { this.x = "abc" }
"abc"
x
"abc"
Chromium 11
Довольно странно, т.к. я проверял на node.js, что по сути есть почти тот же v8, что и в хромиуме
with ({}) { console.log(this) }
DOMWindow
undefined
То есть this в контексте with ({}) используется глобальный
this.a=1;
with ({x:'1'}) {
console.log(this); // { a: 1 }
}
то есть тот же эффект, что есть довольно странно и неправильно.
Однако код приведенный выше:
var x='a';
with({x:'b'}) {
console.log('1:'+x); // 1:b
x = 'c';
console.log('2:'+x); // 2:c
}
console.log('3:'+x); // 3:a
ведёт себя вполне корректно.
Видимо в момент перехода «мапятся» существующие свойства, но несуществующие внутри with не создаются и относятся к вышележащему контексту. И, в принципе, логика в этом есть, иначе доступ к вышележащему был бы затруднён, код
возвращал бы false. Правда конфликты имён могут возникнуть. Так что правильно depricated :)
a = 0;
with ({b: 1, c: 2}) {
a = b + c;
}
a == 3;
возвращал бы false. Правда конфликты имён могут возникнуть. Так что правильно depricated :)
а вас не смущает, что конфликты могут возникнуть внутри и снаружи for? ;)
a = 0;
for (var i = 4; i--;) {
a += i;
}
Ни капли, for не меняет контекст выполнения :)
точно так же, как with)
Неправильно выразился, не выполнения, а цепочку распознавания идентификаторов или как там её. А with её частично меняет, но не очевидно, если не вдаваться в нюансы или их забыть.
Присваивание y ведёт себя по разному в зависимости от того было ли присваивание y перед ним. А если бы было o[someLongExpressionThatReturnObject().toString] = 2; было бы ещё менее очевидно.
var o = {};
with (o) {
y = 1;
console.log(y); // 1
}
console.log(y); // 1
with (o) {
y = 1;
console.log(y); // 1
o.y = 2;
console.log(y); // 2
y = 3;
console.log(y); // 3
}
console.log(y); // 1
Присваивание y ведёт себя по разному в зависимости от того было ли присваивание y перед ним. А если бы было o[someLongExpressionThatReturnObject().toString] = 2; было бы ещё менее очевидно.
Как по мне, так это не недостаток, а вполне логичное поведение.
Во-первых, есть разница между var и let.
Во-вторых, вы можете использовать такой подход:
Во-первых, есть разница между var и let.
Во-вторых, вы можете использовать такой подход:
with({ x: 'abc' }) { }
console.log(x) // undefined
У меня есть только одно место где используется with:
function exec(__code__, scope) { with(scope || global) return eval(__code__); }
Да, я еретик и отступник, горетть мне в аду! Джон Резиг использует with в своей функции для шаблонизирования. Не подскажете зачем?
Это треш конечно…
В принципе если бы не было доступа к global, то было бы весьма юзабельно. В т.ч. для всяких песочниц и eval-ов. А так да, всю малину портит.
Блин, что-ж JavaScript так медленно развивается то? За последние лет 5 наверное ни одной фичи в язык не добавили. Все зациклились на дополнительных библиотеках/API и разгоне, а то, что приходится писать на языке 10-летней давности никого не волнует…
Только вон в Mozilla есть подвижки с поддержкой JavaScript 1.7-1.8 хоть какая-то радость
В принципе если бы не было доступа к global, то было бы весьма юзабельно. В т.ч. для всяких песочниц и eval-ов. А так да, всю малину портит.
Блин, что-ж JavaScript так медленно развивается то? За последние лет 5 наверное ни одной фичи в язык не добавили. Все зациклились на дополнительных библиотеках/API и разгоне, а то, что приходится писать на языке 10-летней давности никого не волнует…
Только вон в Mozilla есть подвижки с поддержкой JavaScript 1.7-1.8 хоть какая-то радость
Погуглите Хабр на тему «JavaScript.next», в частности статьи dsCode и azproduction
любая конструкция плоха в неумелых руках
я его использую для импорта объектов из неймспейса. гадить в глобалы не камильфо, а писать неймспейс перед каждым классом — запарно. поэтому:
$ns= {}
with($ns){
$ns.$Clock=…
}
with($ns){
$ns.$mainClock= new $Clock(… )
}
я его использую для импорта объектов из неймспейса. гадить в глобалы не камильфо, а писать неймспейс перед каждым классом — запарно. поэтому:
$ns= {}
with($ns){
$ns.$Clock=…
}
with($ns){
$ns.$mainClock= new $Clock(… )
}
и как IIFE с производительностью в цикле?
эх когда в JS будет что-то типа using(var f=a.b.c.d[i]){alert(f.x);}
ну и блочная область видимости переменных соответственно…
эх когда в JS будет что-то типа using(var f=a.b.c.d[i]){alert(f.x);}
ну и блочная область видимости переменных соответственно…
Между прочим. Хотя я никогда не использовал with, но теперь жалею, что его запретили. Ведь это была бы отличная замена IIFE и временная мера для let.
ArtemSmirnov писал об этом, но он не сказал, где именно это выгодно использовать.
Решить проблемы «Производительность» и «Безопасность» можно очень легко — запретить использовать в with переменную, только объект:
Это можно использовать вместо IIFE:
Между прочим, у такого подхода есть даже некоторые преимущества по сравнению с let
ArtemSmirnov писал об этом, но он не сказал, где именно это выгодно использовать.
Решить проблемы «Производительность» и «Безопасность» можно очень легко — запретить использовать в with переменную, только объект:
with(obj); // Error
with({ x: 123 }); // Success
Это можно использовать вместо IIFE:
<span>0</span>
<span>1</span>
<span>2</span>
<span>3</span>
for (var i = 4; i--;) {
$$('span')[i].onclick = function () {
alert(i); // fail
};
}
// IIFE
for (var i = 4; i--;) {
$$('span')[i].onclick = function (i) {
return function () {
alert(i); // success
};
}(i);
}
// with
for (var i = 4; i--;) with({ i:i }) {
$$('span')[i].onclick = function () {
alert(i); // success
};
}
Между прочим, у такого подхода есть даже некоторые преимущества по сравнению с let
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Оператор with и почему его не стоит использовать