2010-03-29 12 views
19

Widziałem kod JavaScript zaczynający się od with. To trochę zagmatwane. Co robi i jak można go używać poprawnie?Co robi "z" w JavaScript?

with (sObj) return options[selectedIndex].value; 

Odpowiedz

22

Dodaje do zakresu oświadczeń zawartych w bloku:

return sObj.options[selectedIndex].value; 

może stać:

with (sObj) 
    return options[selectedIndex].value; 

W twoim przypadku, to doens't zrobić dużo. .. ale rozważ następujące:

var a, x, y; 
var r = 10; 
a = Math.PI * r * r; 
x = r * Math.cos(PI); 
y = r * Math.sin(PI /2); 

Staje się:

var a, x, y; 
var r = 10; 
with (Math) { 
    a = PI * r * r; 
    x = r * cos(PI); 
    y = r * sin(PI/2); 
} 

... zapisuje kilka naciśnięć klawiszy. Dokumentacja Mozilla faktycznie robi bardzo dobrą robotę wyjaśniania rzeczy w trochę bardziej szczegółowo (wraz z zalet i wad korzystania IT):

with - Mozilla Developer Center

+0

Używanie lame, podobnie jak w VBA. W Pythonie można zająć się czyszczeniem obiektu jednorazowego użytku. W języku C# jest to wywoływane za pomocą. –

+0

+1 - Hej Justin - miłe wyjaśnienie –

+0

@Mark - Dzięki. Wygląda na to, że powinienem dołączyć zalecenie "nie używać tego". –

1

polecam nie przy użyciu tego powodu problemów z wydajnością, ale co powyższe środki są następujące:

dla obiektu sObj (tutaj prawdopodobnie wybrany element), wszystkie dzieci i właściwości wymienione na tej (lub między kolejnymi nawiasami klamrowymi) traktują to jako swój zakres rodzica.

1

Nie jest funkcją (jak wskazano w tytule pytania przed edycją), ale oświadczeniem. Może to więcej sensu, jeśli próbka kodu jest sformatowany tak:

with (sObj){ 
    return options[selectedIndex].value; 
} 

chodzi o to, co robi (Source)

instrukcji with ustanawia domyślnego obiektu dla zestawu oświadczeń. JavaScript wyszukuje wszelkie niewykwalifikowane nazwy w zestawie instrukcji, aby określić, czy nazwy są właściwościami domyślnego obiektu. Jeśli niekwalifikowana nazwa pasuje do właściwości, właściwość jest używana w instrukcji; w przeciwnym razie używana jest zmienna lokalna lub globalna.

Co oznacza, że ​​w próbce kodu najpierw sprawdza się, czy options jest właściwością sObj. Jeśli jest następnie options dotyczy sObj.options, inaczej sprawdza inne zakresy dla zmiennej zdefiniowanej przez nazwę options

Minusem korzystania z with oświadczenie, że niemożliwe jest, aby wiedzieć, z tylko patrząc na kod, co dostaje dostęp.Są inne lepsze alternatywy, jak pokazano na this article

+0

Podczas gdy reszta odpowiedzi jest prawidłowa, formatowanie ma stosunkowo mało do zrobienia z tym. – belugabob

+0

@belugabob Proszę * przeczytać * odpowiedź zamiast zgadywać co do jej treści. Nigdy nie wspominałem o formatowaniu mającym jakiekolwiek znaczenie dla wyrażenia 'with'. Powiedziałem, że ma więcej sensu *, jeśli jest sformatowany za pomocą nawiasów klamrowych, ponieważ sprawia, że ​​wygląda mniej jak wywołanie funkcji, a bardziej jak instrukcja. – Yacoby

+0

@belugabob Zmieniłem kolejność słów tak, aby trudniej było nie zrozumieć. – Yacoby

2

tym, że z bloku nie trzeba wpisać:

sObj.options[selectedIndex].value 

ale można po prostu użyć:

options[selectedIndex].value 
2

Jego odpowiednikiem

return sObj.options[selectedIndex].value; 

With pozwala wydać blok zdań w argumencie xt określonego obiektu. Dlatego wszystkie instrukcje w bloku with są uważane za elementy obiektu w nawiasach.

To może uczynić kod bardziej czytelnym w czasach, , ale może to również prowadzić do niejednoznaczności, ponieważ zmienne odniesienia mogą mieć wartość sObj lub globalną.

legitimate uses for javascript's "with" statement: D

9

oświadczenie with jest czysty cukier syntaktyczny, ale również może powodować nieprzyjemnych błędów.

Zobacz with Statement Considered Harmful dla wyjaśnienia:

Jeżeli nie można odczytać program i mieć pewność, że wiesz, co ona ma zamiar zrobić, nie można mieć pewności, że to będzie działać poprawnie. Z tego powodu należy unikać instrukcji with.

+2

++ za wskazanie wad "z" –

1

Twój Przykładem może być zapisane jako ...

return sObj.options[selectedIndex].value; 

... jako „o” miejscach oświadczenie wszystkich powiązanych sprawozdań w zakresie dostarczonego przedmiotu. W tym przypadku jest to bezsensowne, ale jeśli wykonujesz wiele operacji na 'sObj', to oszczędzasz dużo pisania.

Całkowicie ficticious przykład ..

with (sObj) 
{ 
    if(options[selectedIndex].value < 10){ 
     options[selectedIndex].value++; 
     total+ = options[selectedIndex].value; 
    } 
} 

Ale powiedział, że, to często zdarza się, że oszczędności można uzyskać wpisując w lepszych sposobów.