2

好吧,当我尝试Object.watch在 Chrome 中使用 polyfill 时,我遇到了问题。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/watch https://gist.github.com/eligrey/384583

polyfill 非常短,您可以阅读它如何删除原始属性并立即定义一个新属性,该值相同但具有覆盖 getter 和 setter。

问题是,如果你使用这个 polyfill 并观察 op:

var o = { p: 1 };
o.watch("p", function (id, oldval, newval) {
  console.log( "o." + id + " changed from " + oldval + " to " + newval );
  return newval;
});

之后,您检查ochrome devtool 下的对象。砰! 对象o现在是空的!其实它还是有属性的p,输入o.p你就会发现o.p = 1

我的问题是,为什么该属性在 Chrome 开发者工具对象属性列表下是不可见的?

注意:如果你不知道/不感兴趣Object.watch,你仍然可以在这个问题上帮助我,只要你理解Object.defineProperty得很好。


编辑:事实证明,它与我想象的完全不同,它创建了一个新属性,只是覆盖了它的 getter 和 setter。引用自https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty “对象中的属性描述符有两种主要形式:数据描述符和访问器描述符。数据描述符是一个具有值的属性,该值可能是可写的,也可能是不可写的。访问器描述符是由 getter-setter 函数对描述的属性。

所以看起来 polyfill 将目标属性从“数据属性”更改为“访问器属性”。我认为这是填充这个的唯一方法?

4

1 回答 1

2
我的问题是,为什么该属性在 Chrome 开发者工具对象属性列表下是不可见的?

答案是:它是可见的,但现在它是一个 getter 和 setter。

Object {}
get p: function () {
set p: function (val) {
__proto__: Object

jsfiddle

但是,如果您问为什么看不到它的值:那是因为该值现在是私有的,只能通过使用 getter 来读取。

console.log(o.p);

更新:读取Mutator 方法

突变方法

维基百科,自由的百科全书

在计算机科学中,mutator 方法是一种用于控制变量更改的方法。它们也被广泛称为'''setter'''方法。通常,setter 伴随着一个 '''getter'''(也称为访问器),它返回私有成员变量的值。mutator 方法,有时称为“setter”,最常用于面向对象的编程中,与封装原则保持一致。根据这一原则,将类的成员变量设为私有以隐藏和保护它们不受其他代码的影响,并且只能通过公共成员函数(mutator方法)进行修改,该函数将所需的新值作为参数,可选地验证它,并修改私有成员变量。

考虑这个例子

function MyClass() {
    var privateVar = 0;

    this.getPrivate = function () {
        return privateVar;
    }

    this.setPrivate = function (value) {
        privateVar = value;
    }
}

var newObject = new MyClass();

console.log(newObject);

console.log(newObject.getPrivate());

输出

MyClass {getPrivate: function, setPrivate: function}
getPrivate: function () {
setPrivate: function (value) {
__proto__: MyClass

0

jsfiddle

您可以查看对象并查看公共方法getPrivatesetPrivate(类似太真实的 getter 和 setter 创建的Object.defineProperty),但看不到成员变量的值privateVariable。您只能通过调用getPrivate公共方法查看值。

于 2013-07-18T09:09:18.133 回答