Как стать автором
Обновить

Комментарии 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»
var забыл выкинуть.
То будет возвращен «abc»

Нет, не будет.
И ещё в догонку:
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
Понял, но всё равно у меня х = 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 не создаются и относятся к вышележащему контексту. И, в принципе, логика в этом есть, иначе доступ к вышележащему был бы затруднён, код
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 её частично меняет, но не очевидно, если не вдаваться в нюансы или их забыть.
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; было бы ещё менее очевидно.
* o.y перед ним
with очень похож на let, imho
Как по мне, так это не недостаток, а вполне логичное поведение.
Во-первых, есть разница между 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 хоть какая-то радость
Погуглите Хабр на тему «JavaScript.next», в частности статьи dsCode и azproduction
любая конструкция плоха в неумелых руках
я его использую для импорта объектов из неймспейса. гадить в глобалы не камильфо, а писать неймспейс перед каждым классом — запарно. поэтому:

$ns= {}

with($ns){
$ns.$Clock=…
}

with($ns){
$ns.$mainClock= new $Clock(… )
}
и как IIFE с производительностью в цикле?
эх когда в JS будет что-то типа using(var f=a.b.c.d[i]){alert(f.x);}
ну и блочная область видимости переменных соответственно…
Let мене блочную видимость
спасибо, нашел топик про него тут
жаль что кроме FF он нигде не работает, проверял IE9,Chrome, Opera, Safari
Между прочим. Хотя я никогда не использовал 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
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории