2013 ve 2015 Güncellemesi (2011'deki orijinal yanıt için aşağıya bakın) :
Bu, ES2015 ("ES6" olarak da bilinir) spesifikasyonundan itibaren değişti: JavaScript artık proxy'lere sahip . Proxy'ler, diğer nesneler için (cepheler üzerinde) gerçek proxy'ler olan nesneler oluşturmanıza izin verir. Aşağıda, alma sırasında dizeler olan tüm özellik değerlerini tamamen büyük harflere çeviren basit bir örnek verilmiştir:
"use strict";
if (typeof Proxy == "undefined") {
throw new Error("This browser doesn't support Proxy");
}
let original = {
"foo": "bar"
};
let proxy = new Proxy(original, {
get(target, name, receiver) {
let rv = Reflect.get(target, name, receiver);
if (typeof rv === "string") {
rv = rv.toUpperCase();
}
return rv;
}
});
console.log(`original.foo = ${original.foo}`); // "original.foo = bar"
console.log(`proxy.foo = ${proxy.foo}`); // "proxy.foo = BAR"
Geçersiz kılmadığınız işlemlerin varsayılan davranışları vardır. Yukarıda, geçersiz kıldığımız tek şey get
, ancak bağlanabileceğiniz işlemlerin tam bir listesi var.
In get
işleyici işlevin argümanlar listesinin:
target
vekalet edilen nesnedir ( original
bizim durumumuzda).
name
(elbette) alınan özelliğin adıdır, bu genellikle bir dizedir ancak aynı zamanda bir Sembol de olabilir.
receiver
this
özellik, veri özelliği yerine erişimci ise, alıcı işlevinde olduğu gibi kullanılması gereken nesnedir . Normal durumda bu ondan devralır, ancak bu proxy veya bir şeydir olabilir tuzak tarafından tetiklenebilir beri herhangi bir şey olabilir Reflect.get
.
Bu, istediğiniz tümünü yakalama alıcı ve ayarlayıcı özelliğiyle bir nesne oluşturmanıza olanak tanır:
"use strict";
if (typeof Proxy == "undefined") {
throw new Error("This browser doesn't support Proxy");
}
let obj = new Proxy({}, {
get(target, name, receiver) {
if (!Reflect.has(target, name)) {
console.log("Getting non-existent property '" + name + "'");
return undefined;
}
return Reflect.get(target, name, receiver);
},
set(target, name, value, receiver) {
if (!Reflect.has(target, name)) {
console.log(`Setting non-existent property '${name}', initial value: ${value}`);
}
return Reflect.set(target, name, value, receiver);
}
});
console.log(`[before] obj.foo = ${obj.foo}`);
obj.foo = "bar";
console.log(`[after] obj.foo = ${obj.foo}`);
Yukarıdakilerin çıktısı:
Varolmayan 'foo' özelliğini alma
[önce] obj.foo = tanımsız
Var olmayan 'foo' özelliğini ayarlama, başlangıç değeri: bar
[after] obj.foo = bar
foo
Henüz varolmadığında geri almaya çalıştığımızda ve tekrar oluşturduğumuzda, ancak ondan sonra değilken "var olmayan" mesajını nasıl aldığımıza dikkat edin.
2011'in yanıtı (2013 ve 2015 güncellemeleri için yukarıya bakın) :
Hayır, JavaScript'in tümünü yakalama özelliği yoktur. Kullandığınız erişimci sözdizimi , spesifikasyonun 11.1.5 Bölümünde ele alınmıştır ve herhangi bir joker karakter veya buna benzer bir şey sunmaz.
Elbette, bunu yapmak için bir işlevi uygulamak olabilir, ama muhtemelen kullanmak istemiyorum tahmin ediyorum f = obj.prop("foo");
ziyade f = obj.foo;
ve obj.prop("foo", value);
yerine obj.foo = value;
(işlev bilinmeyen özelliklerini işlemek için gerekli olurdu).
FWIW, alıcı işlevi (ayarlayıcı mantığıyla uğraşmadım) şuna benzer:
MyObject.prototype.prop = function(propName) {
if (propName in this) {
// This object or its prototype already has this property,
// return the existing value.
return this[propName];
}
// ...Catch-all, deal with undefined property here...
};
Ama yine de, nesneyi kullanma şeklinizi nasıl değiştirdiği için bunu gerçekten yapmak isteyeceğinizi hayal edemiyorum.