标签: es6-proxy

ES6代理集属性陷阱未针对数组长度触发

使用JavaScript ES6 Proxies时,直接分配数组索引时不会触发array.length的set属性陷阱.

例如:

const proxy = new Proxy([], {
    set: function(obj, name, value) {
        console.log(`set: ${name}`);
        obj[name] = value;
        return true;
    }
});
proxy.push(0);
proxy[1] = 1;
Run Code Online (Sandbox Code Playgroud)

Chrome 51和Firefox 47输出:

set: 0  
set: length  
set: 1

虽然我期望:

set: 0  
set: length  
set: 1  
set: length 

这是按规格吗?我找不到任何关于此的信息.

javascript ecmascript-6 es6-proxy

5
推荐指数
1
解决办法
800
查看次数

创建代理的结构化克隆

我有一个从构造函数返回Proxy的类。当我尝试将此类的实例存储在IndexedDB中或使用发送对象时window.postMessage(),收到一条错误消息,指出无法克隆该对象。看来结构化克隆算法无法处理代理对象。

以下代码演示了该错误:

class MyClass {
  constructor() {
    return new Proxy(this, {
      set(target, prop, val, receiver) {
        console.log(`"${prop}" was set to "${val}"`);
        return Reflect.set(target, prop, val, receiver);
      }
    });
  }
}

const obj = new MyClass;

try {
  window.postMessage(obj,'*');
} catch(err) {
  console.error(err);

}
Run Code Online (Sandbox Code Playgroud)

谁能建议解决此问题的方法?我看到了两个潜在的解决方案,但是我不知道如何实现它们:

  1. 不要从构造函数返回Proxy,而是以某种方式在类声明中维护Proxy功能。

  2. 更改代理实例,使其与结构化克隆算法一起使用。

编辑:以下更简单的代码也演示了结构化克隆错误:

const p = new Proxy({}, {});
window.postMessage(p, '*');
Run Code Online (Sandbox Code Playgroud)

javascript es6-proxy

5
推荐指数
1
解决办法
440
查看次数

从现有代理实例中检索原始目标对象

假设我有一个像这样的代理实例:

const getProxy = function(){
    return new Proxy({}, ...);
}

const proxy = getProxy();
Run Code Online (Sandbox Code Playgroud)

稍后,我想从代理中检索目标,有没有办法做到这一点?就像是:

const target = proxy.getOriginalTarget()
Run Code Online (Sandbox Code Playgroud)

javascript node.js es6-proxy

5
推荐指数
3
解决办法
2876
查看次数

如何在Javascript中检查es6代理的类型?

我正在使用 ES6 代理。我已经创建了一个数组的代理,现在当我检查代理的类型时,它给我作为Object类型。

问题:

如何检查我创建的代理是用于数组还是对象?

例子:

const arr = ['a', 'b', 'c'];

const arrProxy = new Proxy(arr, {});

alert(typeof(arrProxy));
Run Code Online (Sandbox Code Playgroud)

更新(解决方案):typeof我们应该使用 而不是使用Array.isArray

const arr = ['a', 'b', 'c'];

const arrProxy = new Proxy(arr, {});

alert(Array.isArray(arrProxy));
Run Code Online (Sandbox Code Playgroud)

javascript es6-proxy

5
推荐指数
1
解决办法
4175
查看次数

如何为 HTMLELement 创建代理

问题

如何为浏览器原生 DOM 对象创建代理?


背景

我想拦截元素样式的设置。所以我为 DOM 对象创建一个代理。但是,当我使用某些函数(例如getComputedStyle().

  const setHandler = (target: any, prop: PropertyKey, value: any, _receiver?: any) => {
    if (/*some condition*/) {
      target[prop] = value
    }
    return true
  }

  const getHandler = (target: any, prop: PropertyKey, _receiver?: any) => {
    return target[prop]
  }

  const style = new Proxy(el.style, {
    get: getHandler,
    set: setHandler
  })
  const classList = new Proxy(el.classList,{
    get: getHandler,
    set: setHandler
  })

  const proxy = new Proxy(el/*HTMLElement*/, {
    get: (target, prop, _receiver) => …
Run Code Online (Sandbox Code Playgroud)

javascript proxy dom ecmascript-6 es6-proxy

5
推荐指数
0
解决办法
1725
查看次数

JavaScript 中的可撤销代理有什么用?

为什么要撤销代理?您能提供一个实际应用吗Proxy.revocable()

根据MDN Proxy.revocable() 文档,我了解它允许垃圾收集。但是,如果你刚刚删除了 Proxy 对象,不是也允许垃圾回收吗?

附录:如果这个问题有问题,请告诉我它是什么,我很乐意改写或添加其他信息。

@艾米:

我认为这似乎是一个不必要的内置功能,因为我可以像这样创建一个可撤销代理:

function createRevocable(o,handlers){
	var revoked = false
	var handlerWrapper = {
		get(...args){
			if(revoked){
				throw Error('Sorry, this object went poof.')
			}
			if(typeof handlers.get == 'function'){
				return handlers.get(...args)
			}else{
				return Reflect.get(...args)
			}
		}
	}
	var p = new Proxy(o,Object.assign({},handlers,handlerWrapper))
	var r = function(){
		revoked = true
	}
	return {r,p}
}

var a = createRevocable({a:1},{})
var prox = a.p
var revoke = a.r
console.log(prox.a) //1
revoke()
console.log(prox.a)
Run Code Online (Sandbox Code Playgroud)

然而,垃圾收集似乎确实是问题所在,因为我可以撤销对该对象的访问,但无法删除 Proxy 对象内对其的内部引用。除非...

javascript es6-proxy

5
推荐指数
1
解决办法
1630
查看次数

如何使 JavaScript Proxy 的处理程序方法成为异步函数?

请参阅 Mozilla 文档中有关Proxy()的内容

一个简单的代理示例:

const handler = {
  get: function(target, prop, receiver) {
    return Reflect.get(target, prop, receiver);
  },
  set: function(target, prop, receiver) {
    return Reflect.set(target, prop, receiver);
  }
};

const proxy = new Proxy(target, handler);
Run Code Online (Sandbox Code Playgroud)

get我在and中有一些异步函数set,所以我想让getsetto 成为async函数。

我期望类似的东西:

const handler = {
  get: async function(target, prop, receiver) {
    await foo();
    return Reflect.get(target, prop, receiver);
  },
  set: async function(target, prop, receiver) {
    await bar();
    return Reflect.set(target, prop, receiver);
  }
};

const …
Run Code Online (Sandbox Code Playgroud)

javascript handler async-await es6-proxy

5
推荐指数
1
解决办法
1388
查看次数

JavaScript 代理在“get”上返回异步值

我有一些从网络服务器获取的对象。对象的某些属性需要额外的异步解析,但出于性能原因我想延迟执行此操作。我试图使用代理来拦截访问,然后在访问时解析属性。我的处理程序看起来像这样

class MyClass {
   type() {
      return "my new class";
   }
}

let myObject = new MyClass();

let proxy = new Proxy(myObject, {
  get: async(target, prop, receiver) => {
    if (prop === "attribute") {
      let newProp = prop + "_parsed";
      if (!(newProp in target)) {
        return await (new Promise((resolve, reject) => { resolve("parsed value") }));
      }
      else {
        return target[newProp];
      }
    }
    else {
      return Reflect.get(target, prop, receiver);
    }
  },
});

console.log(proxy.attribute);  // "parsed value"
console.log(proxy.type()); // "my new class" …
Run Code Online (Sandbox Code Playgroud)

javascript asynchronous es6-proxy

5
推荐指数
1
解决办法
3830
查看次数

使用 ES6 代理和 node.js 的非法调用错误

我无法弄清楚为什么以下代码不起作用:

var os = new Proxy(require('os'), {});
console.log( os.cpus() ); // TypeError: Illegal invocation
Run Code Online (Sandbox Code Playgroud)

然而

var os = require('os');
console.log(Reflect.apply(os.cpus, os, []));
Run Code Online (Sandbox Code Playgroud)

或者

var os = new Proxy(require('os'), {});
console.log( os.platform() );
Run Code Online (Sandbox Code Playgroud)

按预期工作。

node.js es6-proxy

4
推荐指数
1
解决办法
1628
查看次数

ES6代理的主要用例

我最近了解了ES6代理,但我没有看到使用它的充分理由.我的意思是,除非我遗漏了什么,否则可以在没有它的情况下完成所有可以使用Proxy的事情.

例如,大多数人谈论代理时的验证,但可以应用一些JS优点来验证,每个人都很好.如果有人可以睁开眼睛看看代理的一些主要用例,我将不胜感激.谢谢!

javascript proxy ecmascript-6 es6-proxy

4
推荐指数
1
解决办法
1114
查看次数