我有一个抽象类:
abstract class Foo {
abstract bar(): string;
}
Run Code Online (Sandbox Code Playgroud)
我有一些扩展的类Foo:
class Foo1 extends Foo {
bar(): string { return 'foo1'; }
}
class Foo2 extends Foo {
bar(): string { return 'foo2'; }
}
Run Code Online (Sandbox Code Playgroud)
我还有一个类,我要代理的所有方法Foo的Foo。这实际上工作正常,如果我Foo在这个类上定义所有方法。但我宁愿不这样做。我宁愿让Foo定义的方法Foo和编译器知道FooProxy也实现了这些方法,而不必实际实现它们。这可能吗?Proxy 类看起来像这样:
class FooProxy {
public foo: Foo;
constructor(foo: Foo) {
this.foo = foo;
let handler = {
get: function(target: FooProxy, prop: string, receiver: any) {
if(Foo.prototype[prop] !== null) {
return target.foo[prop]; …Run Code Online (Sandbox Code Playgroud) 首先,我要澄清,我知道,with已被弃用,并使用它是通常一个糟糕的做法。
但是,我的问题是关于一个特殊情况:使用特殊Proxy对象作为with.
我正在做一个项目,我必须将一段代码的访问权限限制在全局范围内。
一种方法可能是使用 with 循环eval,它undefined为全局对象的每个属性创建具有值的常量变量,但这似乎比 using 更糟糕with,并且不能限制对使用letand创建的变量的访问const。
hastrap 总是返回true,因此它不允许任何查找或赋值超出with语句gettrap 正常运行,除了它ReferenceError在尝试访问不存在的变量(即属性)时抛出sset trap 正常运行(或者可能包含一些自定义逻辑)target对象没有[[Prototype]](即它是用创建的Object.create(null))target对象具有一个@@unscopables属性,其值为空对象,以允许对每个属性进行范围界定所以,像这样的代码:
const scope = Object.create(null)
Object.assign(scope, {
undefined,
console,
String,
Number,
Boolean,
Array,
Object,
/* etc. …Run Code Online (Sandbox Code Playgroud)我正在研究代理对象、类和私有属性。并遇到了这个错误消息:
/home/marc/projects/playground/pipeline/clsss.js:14
this.#hidden = !this.#hidden;
^
TypeError: Cannot read private member #hidden from an object whose class did not declare it
at Proxy.toggle (/home/marc/projects/playground/pipeline/clsss.js:14:30)
at Object.<anonymous> (/home/marc/projects/playground/pipeline/clsss.js:37:19)
at Module._compile (internal/modules/cjs/loader.js:1118:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1138:10)
at Module.load (internal/modules/cjs/loader.js:982:32)
at Function.Module._load (internal/modules/cjs/loader.js:875:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47
Run Code Online (Sandbox Code Playgroud)
重现代码:
/home/marc/projects/playground/pipeline/clsss.js:14
this.#hidden = !this.#hidden;
^
TypeError: Cannot read private member #hidden from an object whose class did not declare it
at Proxy.toggle (/home/marc/projects/playground/pipeline/clsss.js:14:30)
at Object.<anonymous> (/home/marc/projects/playground/pipeline/clsss.js:37:19)
at Module._compile (internal/modules/cjs/loader.js:1118:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1138:10)
at …Run Code Online (Sandbox Code Playgroud) 我想Proxy在一个ObservableList包含一个名为的自定义类上使用Array.由于Proxy仅在ES6之后可用,我想知道是否有任何替代实现.
我的要求是在ObservableList更改后对观察者进行更新(而不是引起注意),以便观察者总是使用一些过滤或映射方法与observable一起构成.
var activities = new ObservableList(['reading', 'swimming']);
var sAct = activities.filter(function(v) {
return v[0] === 's';
});
// expect sAct.list to be ['swimming']
var meAct = activities.map(function(v) {
return 'I am ' + v;
});
// expect meAct.list to be ['I am reading', 'I am swimming']
activities.list.push('smiling');
console.log(sAct.list, meAct.list);
// expect sAct.list to be ['swimming', 'smiling']
// expect meAct.list to be ['I am reading', 'I am swimming', 'I am …Run Code Online (Sandbox Code Playgroud) 在MDN 上的代理陷阱文档ownKeys中,它指出它将拦截Object.keys()调用:
该陷阱可以拦截以下操作:
Object.getOwnPropertyNames()
Object.getOwnPropertySymbols()
对象.keys()
Reflect.ownKeys()
但是,从我的测试来看,它似乎不适用于Object.keys:
const proxy = new Proxy({}, {
ownKeys() {
console.log("called")
return ["a", "b", "c"]
}
})
console.log(Object.keys(proxy))
console.log(Object.getOwnPropertyNames(proxy))
console.log(Reflect.ownKeys(proxy))Run Code Online (Sandbox Code Playgroud)
我试图在函数代理上调用.toString().
简单地创建一个函数代理并调用toString导致"TypeError:Function.prototype.toString不是通用的",将toString设置为返回原始源会导致"RangeError:超出最大调用堆栈大小",但为toString创建一个get陷阱作品.
为什么简单地设置toString函数不起作用,但是设置get陷阱呢?
function wrap(source) {
return(new Proxy(source, {}))
}
wrap(function() { }).toString()Run Code Online (Sandbox Code Playgroud)
function wrap(source) {
let proxy = new Proxy(source, {})
proxy.toString = function() {
return(source.toString())
}
return(proxy)
}
wrap(function() { }).toString()Run Code Online (Sandbox Code Playgroud)
function wrap(source) {
return(new Proxy(source, {
get(target, key) {
if(key == "toString") {
return(function() {
return(source.toString())
})
} else {
return(Reflect.get(source, key))
} } })) }
wrap(function() { }).toString()Run Code Online (Sandbox Code Playgroud)
我试图创建一个陷阱属性的Proxy对象,Image但即使使用空处理程序,我收到一条错误消息.
TypeError:Node.appendChild的参数1没有实现接口Node.
代理对象假设充当目标对象,所以这让我感到困惑.据我所知,你也应该能够使用DOM节点(?).
另外:我无法开始加载图像并onload在设置src属性时触发处理程序.
我应该如何使用代理,以便我可以"接管"例如"src"属性,否则它会像常规图像对象一样?
我的代码
'use strict';
//--- normal image use ---
var imgNormal = new Image();
imgNormal.onload = function(){
console.log('Normal loaded OK');
document.body.appendChild(imgNormal);
};
imgNormal.src = 'https://i.imgur.com/zn7O7QWb.jpg';
//--- proxy image ---
var imgProxy = new Proxy(Image, { // I also tried with 'new Image()' and HTMLImageElement
set: function(a,b,c,d){
console.log('set '+b);
return Reflect.set(a,b,c,d);
}
});
imgProxy.onload = function(){
console.log('Proxy loaded OK');
document.body.appendChild(imgProxy);
};
imgProxy.src = 'https://i.imgur.com/zn7O7QWb.jpg';
document.body.appendChild(imgProxy); …Run Code Online (Sandbox Code Playgroud)我可以获取一个 Javascript 对象o并从中创建一个新的 Proxy 对象:
let p = new Proxy(object, { ... })
Run Code Online (Sandbox Code Playgroud)
但是有没有办法改变现有对象引用以跟踪原始对象的更改?特别是,有没有办法可以从外部源跟踪对象上新键的添加?
TL:DR; 是否有可能使对象的属性仅是可调用的(作为函数)?
我的意思是
class Foo{
bar(value){
return value
}
}
let newFoo = new Foo()
console.log(newFoo.bar(123)) // should work fine as function is invoked
console.log(newFoo.bar) // here i need to throw or display an error instead of returning valueRun Code Online (Sandbox Code Playgroud)
我尝试使用Proxyand handler.gettrap 做到这一点,但是我不知道如何捕获它是函数调用还是属性访问,
class Foo {
bar(value) {
return value
}
}
const proxied = new Proxy(new Foo(), {
get: function(target, prop, reciver) {
if (prop === 'bar') {
throw new Error('Bar is method need to be invoced') …Run Code Online (Sandbox Code Playgroud)es6-proxy ×10
javascript ×9
ecmascript-6 ×7
angular ×1
mutation ×1
object ×1
private ×1
properties ×1
reflection ×1
tostring ×1
typescript ×1