Dolaylı eval sıkı modu çağrısı
eval()
non-sıkı bağlamlarda nasıl işlediğini anlıyorum, ancak katı modda eval()
kullanma durumunda tamamen benim aklım karıştı. eval()
doğrudan genel kapsamda çağrıldığında, değişkenler eval()
yeni kapsamı içinde tuttu
'use strict';
eval('var a = 1;');
console.log(a); // ReferenceError: a is not defined
Eğer bir yapıyorum ancakdolaylıglobal kapsam eval()
(aynı şey, değil mi?). katı modda Eğer bana, this JSFiddle bakın inanmıyorsun olursa. () gibi davranır:
'use strict';
(0, eval)('var a = 1;'); // indirect call to eval
console.log(a); // 1???
(0, eval)
ne yaptığını anlamıyorsun bile, Why does google main page use (0, obj.func)(args) syntax? bkz.
En azından benim hesabıma göre anlayış nasıl eval()
gerektiği için işi sıkı modda, bunu demek için (olursa olsun eval()
denen, doğrudan veya dolaylı olarak) yeni bir kapsam için değişkenler tanımlanır eval()
çağrı, ancak bu değil, galiba burada. Belirtimi şunları söyledi:
10.4.2 Girme Eval Kod
Aşağıdaki adımları kontrol eval kod için yürütme içeriği girdiğinde gerçekleştirilir:
Eğer bağlam çağırmak yok ya eğer eval kodu eval işlevi doğrudan bir çağrı (15.1.2.1.1) tarafından değerlendirilir, değil o zaman
bir. Eğer küresel bir yürütme içeriği eval kodunu kullanarak olsaydı gibi yürütme içeriği yenidenC10.4.1.1 açıklandığı gibi.
Başka
bir. Arama yürütme içeriği ThisBinding aynı değeri ThisBinding ayarlayın.
b. Arama yürütme içeriği LexicalEnvironment aynı değeri LexicalEnvironment ayarlayın.
c. Arama yürütme içeriği VariableEnvironment aynı değeri VariableEnvironment ayarlayın.Eval kodu strict code, daha sonra ise
bir. İzin verinstrictVarEnvNewDeclarativeEnvironment LexicalEnvironment geçen argüman olarak arama sonucu.
b. LexicalEnvironment ayarlayınstrictVarEnv.
c. VariableEnvironment ayarlayınstrictVarEnv.10.5 eval kodunu kullanarak açıklandığı gibi Declaration Binding Instantiation gerçekleştirin.
Bu durumda tüm büyük tarayıcıları da dahil olmak üzere (ancak bunlarla sınırlı değildir) Internet Explorer 10, Chrome ve Firefox 30 24 - hepsini aynı davranış, pek sanmıyorum, büyük ihtimalle bu bir hata. İkimiz de aynı şeyi yapmak istedim, ve neden bu durumda değil mi?
eval()
(Evet, biliyorum, "tehlike" kullanarak eval()
) - ben sadece istiyorsun anlıyorum mantığı bu işin arkasında olan bir bilmece benim için.
CEVAP
tl;dr
(0, eval)('var a = 1;');
ikinci durumda aslında doğrudan bir çağrı değildir.
Bu daha yaygın olarak görebilirsiniz:
(function(){ "use strict"
var x = eval;
x("var y = 10"); // look at me all indirect
window.y;// 10
eval("var y = 11");
window.y;// still 10, direct call in strict mode gets a new context
})();
Sorun görülebilir:
Eval kod katı kod, (bana: bağlam düzeltme) ise
Ama sıkı eval kod olarak tanımlanır:
Eval kod Kullanımı Sıkı Direktif içeren bir Yönerge, bir Prolog ile başlar, ya da eğer eval çağrısı doğrudan bir çağrı ise sıkı eval kod.
Çağrı değil, doğrudan yana, eval kodunu sıkı eval kod ve yürütme genel kapsamlı.
Tüm büyük karlar elde edebilirsiniz.
"Eval Kodu" eval
. doğrudan veya dolaylı çağrı daha genel.
Kontrol edelim tam özellikleri for the eval
function
15.1.2.1 eval (x)
Eval fonksiyonunu tek bir argüman ile x çağrıldığında, aşağıdaki adımlar takip edilir:
Eğer Türü(x) Dize ise, x dönün.
Prog bir Program olarak x ayrıştırma sonucu ECMA kodu olalım. Eğer ayrıştırma başarısız olursa, SyntaxError istisnası (ama Ayrıca bakınız Madde 16) atmak.
EvalCtx sonucu olsunyeni bir yürütme içeriği kurmak(10.4.2) eval kod prog.
Sonuç program prog değerlendirme sonucu olsun.
Çalışan yürütme bağlam evalCtx, önceki yürütme içeriği geri çıkın. ...
Yani, 10.4.2, bize, keşfedelim, özel içeri ilk tümcesi bak sana gösterdi:
Yoksa arama bağlam ya da eğer eval kod değil değerlendirilmiş tarafından doğrudan bir çağrı (15.1.2.1.1) eval fonksiyonu sonra ... Yeniden yürütme içeriği sanki bir genel yürütme içeriği
Direct call nedir?
Eval işlevi doğrudan bir çağrı iki aşağıdaki koşulları karşılayan bir CallExpression olarak ifade edilir:
Bu CallExpression içinde MemberExpression değerlendirilmesi sonucu Referans taban değeri kaydı gibi bir ortam var ve referans ismini"". eval
Soyut işlem, bu Başvuru ile GetValue argüman olarak arama sonucu standart yerleşik işlev 15.1.2.1 tanımlanır.
Her iki durumda da MemberExpression
nedir?
eval('var a = 1;');
referans bir adı var değerlendirme sonucu doğrusu eval
GetValue
çözünürlük arama fonksiyonuna döner.
(0, eval)('var a = 1;');
üye ifade değerlendirme sonucudeğilbaşvuru isim eval
. (Gerçi GetValue) işlevi yerleşik çözmek.
Referans isimleri ne?
Bölüm 8.7 in the spec anlatıyor:
Başvuru çözülmüş adı bağlayıcıdır. Başvuru üç bileşen, temel değeri, belirtilen ada ve Boolean değerli sıkı referans bayrağı oluşmaktadır. Temel değeri tanımsız, bir Nesne, bir Boolean, bir Dize, bir Sayı veya bir ortam kaydı (10.2.1). Tanımsız bir taban değer bir başvuru bağlama çözülemedi gösterir. Başvurulan adı bir Dize.
Bu bize GetReferencedName
içine bakmak gerekir:
GetReferencedName(V). Döner referans V. başvurulan ad bileşeni
İşlevini değerlendirirken 27 ** ifade doğru olduğu sürece, bu adlandırma aslında, çünkü dolaylı bir çağrıdır.
nedir &; sıkı modu " " ve nasıl k...
eval-sonra-yük vs modu kanca...
Düğüm sıkı modu zorlamak için bir yolu...
Sıkı modu daha fazla ölçülebilir mi?...
JSHint sıkı modu ve JQuery: '$�...