简体   繁体   English

如何拦截使用文字符号创建的unknwon对象的已知属性值分配

[英]How to intercept a known property value assignment of an unknwon object created using literal notation

This question is a continuation of another I asked here: How to intercept and modify a specific property for any Object 这个问题是我在这里问的另一个问题的延续: 如何拦截和修改任何对象的特定属性

This is a method used to intercept any object's property of a certain name with the objective of changing the value or do a certain action when it is assigned or read: 这是一种用于拦截某个名称的任何对象的属性的方法,目的是在分配或读取值时更改值或执行某些操作:

 Object.defineProperty(Object.prototype, "my_property", { set: function (value) { this._value = value; }, get: function () { return "changed"; } }); var some_object = {}; some_object.my_property = "unchanged"; document.body.innerHTML += some_object.my_property; 
 My property value is: 

While that method is working fine for values assigned to or read from properties after the object has been created, example: 尽管该方法对于创建对象后分配给属性或从属性读取的值都可以正常工作,例如:

var some_object = {}; // or new Object()
some_object.some_property = "some_value"; // triggers setter
console.log(some_object.some_property);   // triggers getter

It won't trigger the getter and setter if the property has been initialized together with the object using literal notation, like so: 如果已使用文字符号将属性与对象一起初始化,则不会触发getter和setter,如下所示:

var some_object = {some_property: "some_value"}; // does not trigger setter
console.log(some_object.some_property);          // does not trigger getter

How can I adapt the previous strategy so that it can also work with the literal notation or is there a different way of achieving this using a completely different method? 我如何才能适应以前的策略,使其也可以使用文字表示法,或者有完全不同的方法来实现这一目标? Perhaps by intercepting the creation of any object through literal notation, similar to monkey patching the Object.create() function? 也许通过文字表示法拦截任何对象的创建,类似于猴子修补Object.create()函数?

Keep in mind that this is only to target a property of a known name on any unknown object. 请记住,这只是针对任何未知对象的已知名称的属性。

There's no way I know of to achieve the effect you're looking for. 我无法知道要达到您想要的效果。 An assignment with = will cause your object to go through the Prototype chain and use the get method on the Object prototype. 带有=的赋值将使您的对象通过Prototype链,并在Object原型上使用get方法。 However, a literal assignment will place it directly on your new object. 但是,文字分配会将其直接放置在新对象上。 It's the rules of Javascript. 这是Javascript的规则。 For more information I'd suggest reading You Don't Know JS, This & Object Prototypes, Chapter 5, specifically the Setting & Shadowing Properties section. 有关更多信息,建议您阅读《您不知道JS,本和对象原型》第5章,特别是“ 设置和阴影属性”部分。

Relevant part: 相关部分:

We will now examine three scenarios for the myObject.foo = "bar" assignment when foo is not already on myObject directly, but is at a higher level of myObject's [[Prototype]] chain: 现在,当foo尚未直接位于myObject上但位于myObject的[[Prototype]]链的更高级别时,我们将研究三种方案的myObject.foo =“ bar”分配:

  1. If a normal data accessor (see Chapter 3) property named foo is found anywhere higher on the [[Prototype]] chain, and it's not marked as read-only (writable:false) then a new property called foo is added directly to myObject, resulting in a shadowed property. 如果在[[Prototype]]链上更高的位置发现了一个名为foo的常规数据访问器(请参见第3章)属性,并且未将其标记为只读(可写:false),则将一个名为foo的新属性直接添加到myObject中。 ,导致阴影属性。
  2. If a foo is found higher on the [[Prototype]] chain, but it's marked as read-only (writable:false), then both the setting of that existing property as well as the creation of the shadowed property on myObject are disallowed. 如果在[[Prototype]]链上找到foo,但是将其标记为只读(可写:false),则既不允许设置该现有属性,也不允许在myObject上创建阴影属性。 If the code is running in strict mode, an error will be thrown. 如果代码在严格模式下运行,将引发错误。 Otherwise, the setting of the property value will silently be ignored. 否则,将默默忽略属性值的设置。 Either way, no shadowing occurs. 无论哪种方式,都不会发生阴影。
  3. If a foo is found higher on the [[Prototype]] chain and it's a setter (see Chapter 3), then the setter will always be called. 如果在[[Prototype]]链上找到一个foo,并且它是一个setter(请参见第3章),则将始终调用该setter。 No foo will be added to (aka, shadowed on) myObject, nor will the foo setter be redefined. 不会将foo添加到myObject(也称为阴影)中,也不会重新定义foo setter。 Most developers assume that assignment of a property ([[Put]]) will always result in shadowing if the property already exists higher on the [[Prototype]] chain, but as you can see, that's only true in one (#1) of the three situations just described. 大多数开发人员都认为,如果属性[[Put]]的赋值在[[Prototype]]链上的较高位置已经存在,则总是会产生阴影,但是如您所见,这仅是其中之一(#1)刚刚描述的三种情况。

If you want to shadow foo in cases #2 and #3, you cannot use = assignment, but must instead use Object.defineProperty(..) (see Chapter 3) to add foo to myObject. 如果要在情况2和情况3下遮盖foo,则不能使用=赋值,而必须使用Object.defineProperty(..)(请参阅第3章)将foo添加到myObject中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM