- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我在使用 Proxy 类时遇到了这个有趣的错误:
TypeError: 'set' on proxy: trap returned truish for property 'users' which exists in the proxy target as a non-configurable and non-writable data property with a different value
我有一个递归创建代理对象属性的库,其中任何非原始属性都是代理对象本身,等等:
let mcProxy = function (target) {
const mirrorCache = {};
return new Proxy(target, {
set: function (target, property, value, receiver) {
if (mirrorCache[property]) {
throw new Error(`property ${property} has already been set`);
}
mirrorCache[property] = true;
Object.defineProperty(target, property, {
writable: false,
value: (value && typeof value === 'object') ? mcProxy(value) : value
});
return true;
}
});
};
exports.create = function (val) {
val && assert.equal(typeof val, 'object', 'val must be an object');
return mcProxy(val || {});
};
上述库代码的实际使用:
//bash
$ npm install proxy-mcproxy
// nodejs
let McProxy = require('proxy-mcproxy');
let val = McProxy.create();
val.users = [];
val.users = 3; // kaaaboom..error!
但是当我第一次设置用户属性时,我得到了这个问题标题中的错误!
在我上面的库代码中,mirrorCache
是一种检查属性是否已预先设置的方法。我想做的是抛出一个错误,即使我们没有处于strict
模式,所以mirrorCache
似乎是必要的所以我自己做簿记。
也许有不同或更好的方法来实现我想要实现的目标?这是我的目标:
最佳答案
查看以下内容,ECMA 规范的第 9.5.9 节:
引人入胜的读物我相信你会同意的。
我认为这两个关键行是:
- Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, P, V, Receiver»)).
和同样深奥的:
- If targetDesc is not undefined, then
a. If IsDataDescriptor(targetDesc) and targetDesc.[[Configurable]] is false and targetDesc.[[Writable]] is false, then
i. If SameValue(V, targetDesc.[[Value]]) is false, throw a TypeError exception.
在NOTE部分有这样的相关评论:
Cannot change the value of a property to be different from the value of the corresponding target object property if the corresponding target object property is a non-writable, non-configurable own data property.
该注释试图将其翻译成英文,但并未指明关键细节,即步骤的时间安排。第 9 点是您的 setter (trap
) 被调用的位置。不幸的是,它检查属性是否可写的位是第 14 点。因此在执行检查时,属性确实是不可写和不可配置的。
解决此问题的一种方法是通过在 defineProperty
中加入 configurable: true
使属性可配置。我并不完全遵循您的用例,因此我无法判断这是否是一个可以接受的折衷方案。
我也想知道为什么您首先需要将这些属性设置为不可写。如果底层对象将始终通过其代理访问,那么您可以完全控制所有 set
调用。我什至不确定为什么您需要 mirrorCache
而不仅仅是检查该属性是否已经在目标对象中。如果您不能假设对象将始终通过其代理访问,那么您似乎已经输掉了这场战斗,因为属性可以在您一无所知的情况下更改。
这样的东西看起来很接近你想要的:
let mcProxy = function (target) {
return new Proxy(target, {
set: function (target, property, value) {
if (Object.prototype.hasOwnProperty.call(target, property)) {
throw new Error(`property ${property} has already been set`);
}
target[property] = (value && typeof value === 'object') ? mcProxy(value) : value;
return true;
}
});
};
它需要更多调整才能正确使用数组,但我不清楚您希望支持哪些数组方法。
关于javascript - 代理类的 TypeError - TypeError : 'set' on proxy: trap returned truish for property,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46227721/
您好,下面是我在 AWS 中创建启用了弹性 IP 的实例的模板。但是我不确定我哪里出错了。我已经通过在线 json 验证器验证了 json,仍然面临问题请帮忙 { "AWSTemplateForm
标题有点乱,但已经说明了一切。我想在一个属性的属性上有一个属性观察器: class A { var b: B init() { b = B() } fu
假设我的一个 Controller 中有这样的方法: [Route("api/Products")] public IQueryable GetProducts() { return db.P
这有效: // @flow import React, {Component} from 'react'; type Props = {}; class Delete extends Componen
我有一个 ViewModelBase 类,我在其中为 INotifyPropertyChanged 接口(interface)定义了 RaisePropertyChanged 方法。大多数 MVVM
我创建了类: class StorageBase { public Queue Slices {get;set;} } 和 wpf 自定义控件,它具有 StorageBase 类型的依赖属性
我的 java 应用程序问题是 log4j2 系统日志不是写在 'local1.log' 中而是'消息'。我的/etc/rsyslog.conf 在/etc/rsyslog.conf 中配置为 'lo
为什么需要在对象中使用 this.property = property ?它是用来定义对象的“外部世界”的属性吗? function Person(property) { this.property
摘要: 这个问题是关于属性的继承与从彼此继承属性的类的内部和外部的不同读/写访问相结合。 详细信息: 我有一个类 A 和另一个继承自 A 的类 B。 A 中声明了属性someProperty。我希望该
我正在开发 ASP.NET MVC 应用,设计域模型,使用(测试)新的 EF Code First 功能。 我有一个可能有也可能没有截止日期的事件实体,处理它的最佳方法是什么? 1 个属性: publ
我在配置项目时经常使用它们,但大多数情况下都是按照指示添加 fragment 。我完全不知道哪个文件到底是做什么的。谁能清楚地说明每个文件的用途。 到目前为止我认为 local.properties
在运行 python 文件以使用 rasa nlu 训练文件时,我在命令提示符下收到此错误 我目前正在使用 Windows 10 rasa_core==0.8.2 rasa_nlu==0.11.4 p
我在这方面遇到了一些麻烦,尽管我已经搜索了答案,但还是找不到。 为了使用 AsyncAppender,我看到了很多不同的 log4j 配置,无论如何,它们都与 .properties 配置文件无关。
我正在编写一个 Python 类,并使用 @property 装饰器为该类创建属性。 我在文档中没有找到太多关于这个装饰器的信息,但是从我可以从 Stack Overflow 和我的 Python l
在 gradle 任务中,我可以创建这样的路径: System.env.FOLDER_PATH + '/subFolder' 但我想在我的 gradle.properties 中设置它,所以它会像 s
如何在属性文件的 log4j2 中创建键值对? 我知道在 log4j 版本 1 中它是这样完成的: log4j.appender.x.additionalFields={'key': 'value'}
我想通了 struct PropertyTest { @property int x() { return val; } @property void x( int newVal )
我有 REST (Jersey) webservice,它利用了一些编码/解码到/来自 XML 的数据对象。数据对象位于 webservice war 所依赖的单独项目/jar 中。 我使用 MOXy
我正在创建一个 LinkedList 类: function LinkedList(){ ... 有什么区别: this.addNode = function(data){
关于语义的快速问题:) 如果我正在编写一个协议(protocol),这是首选: // (a) @protocol MyProtocol @property (nonatomic, copy) NSSe
我是一名优秀的程序员,十分优秀!