如何拦截使用文字表示法创建的 unknwon 对象的已知属性值分配 [英] How to intercept a known property value assignment of an unknwon object created using literal notation

查看:48
本文介绍了如何拦截使用文字表示法创建的 unknwon 对象的已知属性值分配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题是我在这里问的另一个问题的延续:如何拦截和修改任何对象的特定属性

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

如果使用文字符号将属性与对象一起初始化,则不会触发 getter 和 setter,如下所示:

It won't trigger the getter and setter if the property has been initialized together with the object using literal notation, like so:

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

我如何调整以前的策略,使其也可以使用文字符号,或者是否有使用完全不同的方法实现这一目标的不同方法?也许通过文字符号拦截任何对象的创建,类似于猴子修补 Object.create() 函数?

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?

请记住,这只是针对任何未知对象上的已知名称的属性.

Keep in mind that this is only to target a property of a known name on any unknown object.

推荐答案

据我所知,没有办法达到您想要的效果.带有 = 的赋值将使您的对象通过 Prototype 链并在 Object 原型上使用 get 方法.但是,文字赋值会将其直接放置在您的新对象上.这是 Javascript 的规则.有关更多信息,我建议您阅读你不知道的 JS,这个 &对象原型,第 5 章,特别是 设置&阴影属性部分.

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. However, a literal assignment will place it directly on your new object. It's the rules of Javascript. For more information I'd suggest reading You Don't Know JS, This & Object Prototypes, Chapter 5, specifically the Setting & Shadowing Properties section.

相关部分:

我们现在将检查 myObject.foo = "bar" 的三个场景当 foo 还没有直接在 myObject 上,而是在一个myObject 的 [[Prototype]] 链的更高级别:

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:

  1. 如果找到一个名为 foo 的普通数据访问器(参见第 3 章)属性[[Prototype]] 链上任何更高的位置,并且没有标记为只读 (writable:false) 然后添加一个名为 foo 的新属性直接传递给 myObject,从而产生阴影属性.
  2. 如果 foo 是在 [[Prototype]] 链上找到更高的位置,但它被标记为只读(writable:false),然后将该现有属性的设置都设置为以及在 myObject 上创建 shadowed 属性是不允许.如果代码在严格模式下运行,则会出现错误抛出.否则,属性值的设置将被静默忽略.无论哪种方式,都不会发生阴影.
  3. 如果发现 foo 更高[[Prototype]] 链,它是一个 setter(见第 3 章),然后setter 将始终被调用.不会将 foo 添加到(又名,阴影on) myObject,也不会重新定义 foo setter.大多数开发人员假设分配一个属性 ([[Put]]) 总是会导致如果属性已经存在于 [[Prototype]] 的更高位置,则进行阴影处理链,但正如您所看到的,这仅适用于三个中的一个(#1)刚刚描述的情况.

如果你想在 #2 和 #3 的情况下隐藏 foo,你不能使用 =赋值,但必须改为使用 Object.defineProperty(..)(参见第 3 章)将 foo 添加到 myObject.

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.

这篇关于如何拦截使用文字表示法创建的 unknwon 对象的已知属性值分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆