GÜNCELLEME 2015:
As tarafından işaret 7 'nin cevabı , şimdi ES6 (2015 ECMAScript) sonuçlandığı kamuya, daha uygun dokümantasyon artık kullanılabilir:
Orijinal cevap ((tarihsel) anlayış ve ekstra örnekler için) :
Reflection proposalİlerlemiştir görünüyor Taslak ECMAScript 6 Şartname . Bu belge şu anda Reflect-nesnenin yöntemlerini özetlemektedir ve yalnızca Reflect-nesnenin kendisi hakkında şunları belirtmektedir:
Yansıtma nesnesi tek bir sıradan nesnedir.
Reflect nesnesinin [[Prototype]] dahili yuvasının değeri, standart yerleşik Object prototip nesnesidir (19.1.3).
Reflect nesnesi bir işlev nesnesi değildir. [[Construct]] dahili bir metodu yoktur; Reflect nesnesini yeni operatörle bir yapıcı olarak kullanmak mümkün değildir . Reflect nesnesinin ayrıca bir [[Call]] dahili yöntemi yoktur; Reflect nesnesini bir işlev olarak çağırmak mümkün değildir.
Ancak, ES Harmony'de amacına dair kısa bir açıklama var :
"@Reflect" modülü birden çok amaca hizmet eder:
- Artık modüllerimiz olduğuna göre, "@reflect" modülü, daha önce Object üzerinde tanımlanmış yansıtma yöntemlerinin çoğu için daha doğal bir yerdir. Geriye dönük uyumluluk amaçları için, Object üzerindeki statik yöntemlerin kaybolması pek olası değildir. Ancak, yeni yöntemler muhtemelen Object yapıcısından ziyade “@reflect” modülüne eklenmelidir.
- Küresel bir Proxy bağlama ihtiyacını ortadan kaldıran proxy'ler için doğal bir yuva.
- Bu modüldeki çoğu yöntem, Proxy tuzaklarıyla bire bir eşleşir. Proxy işleyicileri, aşağıda gösterildiği gibi işlemleri uygun şekilde iletmek için bu yöntemlere ihtiyaç duyar.
Dolayısıyla, Reflectnesne, birçoğu genel Nesnede tanımlanan ES5 yöntemleriyle örtüşüyor gibi görünen bir dizi yardımcı program işlevi sağlar.
Ancak bu, çözmeyi amaçladığı mevcut sorunları veya hangi işlevselliğin eklendiğini gerçekten açıklamıyor. Bunun yanıltılabileceğinden şüpheleniyordum ve aslında, yukarıdaki armoni spesifikasyonu , 'bu yöntemlerin normatif olmayan, yaklaşık uygulaması' ile bağlantılı .
Bu kodu incelemek, kullanımı hakkında (daha fazla) fikir verebilir, ancak şükürler olsun ki Reflect nesnesinin neden yararlı olduğunun birkaç nedenini özetleyen bir wiki var :
(Aşağıdaki metni, bundan sonra referans olması için kopyaladım (ve biçimlendirdim) kaynak çünkü bulabildiğim tek örnek bunlar . Bunun yanı sıra, mantıklı, zaten iyi bir açıklamaları var ve sorunun applyörneğine dokunuyorlar .)
Daha kullanışlı dönüş değerleri
Reflectİçindeki birçok işlem, ve Objectgibi üzerinde tanımlanan ES5 işlemlerine benzer . Bununla birlikte, özellik başarıyla tanımlandığında veya başka bir şekilde atıldığında geri döneceği için , yalnızca özelliğin başarıyla tanımlanıp tanımlanmadığını gösteren bir boole döndürmek için belirtilir. Bu, bu kodu yeniden düzenlemenizi sağlar:Reflect.getOwnPropertyDescriptorReflect.definePropertyObject.defineProperty(obj, name, desc)objTypeErrorReflect.defineProperty(obj, name, desc)
try {
Object.defineProperty(obj, name, desc);
} catch (e) {
}
Buna:
if (Reflect.defineProperty(obj, name, desc)) {
} else {
}
Böyle bir mantıksal başarı durumu döndüren diğer yöntemler, Reflect.set(bir özelliği güncellemek için), Reflect.deleteProperty(bir özelliği silmek için), Reflect.preventExtensions(bir nesneyi genişletilemez hale getirmek için) ve Reflect.setPrototypeOf(bir nesnenin prototip bağlantısını güncellemek için).
Birinci sınıf işlemler
ES5'te, bir nesnenin objbelirli bir özellik adını tanımlayıp tanımlamadığını veya miras aldığını tespit etmenin yolu yazmaktır (name in obj). Benzer şekilde, bir özelliği silmek için kullanılır delete obj[name]. Adanmış sözdizimi güzel ve kısa olsa da, aynı zamanda işlemi birinci sınıf bir değer olarak iletmek istediğinizde bu işlemleri işlevlere açıkça sarmanız gerektiği anlamına gelir.
İle Reflect, bu işlemler birinci sınıf işlevler olarak kolayca tanımlanır:
Reflect.has(obj, name)işlevsel eşdeğeridir (name in obj)ve Reflect.deleteProperty(obj, name)aynı şeyi yapan bir işlevdirdelete obj[name].
Daha güvenilir fonksiyon uygulaması
ES5'te, fbir dizi olarak paketlenmiş değişken sayıda argüman içeren argsve thisdeğeri bağlayan bir işlevi çağırmak istendiğinde obj, şöyle yazılabilir:
f.apply(obj, args)
Ancak, fkasıtlı veya kasıtsız olarak kendi applyyöntemini tanımlayan bir nesne olabilir . Yerleşik applyişlevin çağrıldığından gerçekten emin olmak istediğinizde , genellikle şöyle yazar:
Function.prototype.apply.call(f, obj, args)
Bu sadece ayrıntılı değil, anlaşılması da hızla zorlaşıyor. İle Reflectartık daha kısa ve anlaşılması daha kolay bir şekilde güvenilir bir işlev çağrısı yapabilirsiniz:
Reflect.apply(f, obj, args)
Değişken bağımsız değişken yapıcıları
Değişken sayıda argüman içeren bir yapıcı işlevi çağırmak istediğinizi düşünün. ES6'da, yeni yayılma sözdizimi sayesinde, aşağıdaki gibi kod yazmak mümkün olacaktır:
var obj = new F(...args)
ES5, bir tek kullanabilirsiniz çünkü bu, zor yazma etmektir F.applyveya F.callbağımsız değişken bir sayı ile bir işlevi çağırmak için, ama hiç yoktur F.constructişlev newbağımsız değişken bir sayı ile fonksiyonu. İle Reflectartık ES5'te yazılabilir:
var obj = Reflect.construct(F, args)
Proxy tuzakları için varsayılan yönlendirme davranışı
Kullanırken Proxymevcut nesneleri sarmak için nesneleri, bir şeyler yapma ve sonra sarılmış nesneye dinlenen operasyonu uygulamak genellikle "varsayılan şey yapmak" na, bir operasyon yolunu kesmek için çok yaygındır. Örneğin, bir nesneye tüm özellik erişimlerini kaydetmek istediğimi varsayalım obj:
var loggedObj = new Proxy(obj, {
get: function(target, name) {
console.log("get", target, name);
}
});
ReflectVe ProxyAPI'ler tandem tasarlanan her biri için öyle ki, Proxyüzerine tuzak, karşılık gelen bir yöntem vardır Reflecto "varsayılan şeyi yapar". Bu nedenle, bir Proxy işleyicisi içinde "varsayılanı yapmak" istediğiniz her zaman, yapılacak doğru şey, her zaman Reflectnesnede karşılık gelen yöntemi çağırmaktır :
var loggedObj = new Proxy(obj, {
get: function(target, name) {
console.log("get", target, name);
return Reflect.get(target, name);
}
});
Dönüş türü Reflectyöntemleri dönüş türü ile uyumlu olması sağlanır Proxytuzaklar.
Erişimcilerin bu bağlamasını kontrol edin
ES5'te genel bir mülk erişimi veya mülk güncellemesi yapmak oldukça kolaydır. Örneğin:
var name = ...
obj[name]
obj[name] = value
Reflect.getVe Reflect.setyöntemleri aynı şeyi, ama ayrıca bir son isteğe bağlı argüman olarak bir kabul etmesine izin receiveraçıkça ayarlamak için olanak sağlar parametresini thisözelliği almak zaman -bağlayıcı / set bir erişimci geçerli:
var name = ...
Reflect.get(obj, name, wrapper)
Reflect.set(obj, name, value, wrapper)
Bu, bazen sarmaladığınızda objve erişimcideki herhangi bir kendi kendine göndermenin sarmalayıcınıza yeniden yönlendirilmesini istediğinizde yararlıdır , örneğin obj:
var obj = {
get foo() { return this.bar(); },
bar: function() { ... }
}
Arama Reflect.get(obj, "foo", wrapper), this.bar()aramanın adresine yeniden yönlendirilmesine neden olur wrapper.
Mirastan kaçının __proto__
Bazı tarayıcılarda, __proto__bir nesnenin prototipine erişim sağlayan özel bir özellik olarak tanımlanır. ES5 Object.getPrototypeOf(obj), prototipi sorgulamak için yeni bir yöntemi standartlaştırdı . Reflect.getPrototypeOf(obj)tam olarak aynı şeyi yapar, ancak bu Reflectaynı zamanda Reflect.setPrototypeOf(obj, newProto)nesnenin prototipini ayarlamak için bir karşılık gelen tanımlar . Bu, bir nesnenin prototipini güncellemenin ES6 uyumlu yeni yoludur.
: O Not setPrototypeOf ayrıca üzerinde varObject (doğru tarafından işaret edildiği gibi KNU 'ın comment )!
DÜZENLEME:
Yan not ( S'ye yapılan yorumları ele alır) : AçıklayanRealms ve Loadernesneleri açıklayan 'S: ES6 Modülleri ve HTML İçe Aktarmaları' üzerine kısa ve basit bir cevap var .
Bu bağlantıda başka bir açıklama sunulmaktadır :
Bir bölge nesnesi, kendi küresel nesnesi, standart kitaplığın kopyası ve "içsel" (Object.prototype'nin başlangıç değeri gibi küresel değişkenlere bağlı olmayan standart nesneler) ile ayrı bir küresel ortam kavramını özetler.
Genişletilebilir web : Bu, <iframe>DOM olmadan aynı orijinin dinamik eşdeğeridir
.
Yine de bahsetmeye değer: tüm bunlar hala taslak halinde, bu taşa kazınmış bir özellik değil! ES6, bu nedenle tarayıcı uyumluluğunu aklınızda bulundurun!
Bu yardımcı olur umarım!
Reflectsadece bir kapsayıcıdırRealmveLoadernesneler, ama ikincisi ikisini de bilmiyorum.