【问题标题】:How to intercept a known property value assignment of an unknwon object created using literal notation如何拦截使用文字表示法创建的未知对象的已知属性值分配
【发布时间】:2017-10-21 13:01:41
【问题描述】:

这个问题是我在这里提出的另一个问题的延续:How to intercept and modify a specific property for any Object

这是一种用于拦截任何对象的某个名称的属性的方法,目的是在赋值或读取时更改值或执行某个操作:

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: 

虽然该方法适用于在对象创建后分配给属性或从属性中读取的值,例如:

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

如果属性已使用字面表示法与对象一起初始化,则不会触发 getter 和 setter,如下所示:

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

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

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

【问题讨论】:

    标签: javascript object monkeypatching


    【解决方案1】:

    我不知道有什么方法可以达到您想要的效果。带有= 的赋值将导致您的对象通过原型链并在对象原型上使用get 方法。但是,文字赋值会将其直接放在您的新对象上。这是Javascript的规则。有关更多信息,我建议阅读你不知道 JS,This & Object Prototypes,第 5 章,特别是 Setting & Shadowing Properties 部分。

    相关部分:

    我们现在将检查 myObject.foo = "bar" 的三个场景 当 foo 尚未直接在 myObject 上时分配,但在 myObject 的 [[Prototype]] 链的更高级别:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-31
      • 2018-04-16
      • 1970-01-01
      • 2018-09-07
      • 2017-09-02
      • 2021-02-20
      • 2014-07-18
      • 2014-11-27
      相关资源
      最近更新 更多