Object.prototype .__ defineGetter __(和__defineSetter__)polyfill

时间:2014-12-10 11:34:38

标签: javascript getter-setter polyfills

我知道__defineGetter__(和__defineSetter__)方法名称确实是weird and deprecated,但我发现它比Object.defineProperty更方便。比较自己:

//Readable
Something.prototype.__defineGetter__("name", function() {return this._name;});
//Uh... - what?
Object.defineProperty(Something.prototype, "name", {
                       get: function() {return this._name;}
                     });

因为,正如我所说,这种方法已被弃用。因此,我正在创建一个polyfill,以便将其重新投入商业:

if(!Object.prototype.__defineGetter__) {
  Object.prototype.__defineGetter__ = function(name, func) {
    Object.defineProperty(this, name, {
      get: func
    });
  }
}

它实际上只是调用标准Object.defineProperty。我可以将__defineGetter__命名为我想要的任何名称。我只是决定坚持已经存在的东西。

这里的问题是,如果我在同一媒体资源上使用__defineGetter____defineSetter__ polyfill,我会两次调用Object.defineProperty

我的问题是:在同一财产上拨打Object.defineProperty两次是否可以?例如,它没有覆盖某些东西吗?

2 个答案:

答案 0 :(得分:2)

要在再次致电set时保留旧的getdefineProperty,您在添加getter或setter时必须将其拉出来:

var proto = Object.prototype;

proto.__defineGetter__ = proto.__defineGetter__ || function(name, func) {
    var descriptor = Object.getOwnPropertyDescriptor(this, name);
    var new_descriptor = { get: func, configurable: true};
    if (descriptor) {
        console.assert(descriptor.configurable, "Cannot set getter");
        if (descriptor.set) new_descriptor.set = descriptor.set; // COPY OLD SETTER
    }
    Object.defineProperty(this, name, new_descriptor);
};

proto.__defineSetter__ = proto.__defineSetter__ || function(name, func) {
    var descriptor = Object.getOwnPropertyDescriptor(this, name);
    var new_descriptor = { set: func, configurable: true};
    if (descriptor) {
        console.assert(descriptor.configurable, "Cannot set setter");
        if (descriptor.get) new_descriptor.get = descriptor.get; // COPY OLD GETTER
    }
    Object.defineProperty(this, name, new_descriptor);
};

答案 1 :(得分:0)

所以你不喜欢使用defineProperty,这很好。但是,为什么要使用__defineGetter____defineSetter__呢?在我看来,这看起来更糟。

早在2013年3月,我遇到了与催吐剂代码相同的问题,这就是为什么我制作了一个simple 41 LOC micro-library,你可以通过命令安装它:

npm install dictionary

使用这个微库,您可以定义这样的getter和setter:

Something.prototype.define({
    get name() {
        return this._name;
    },
    set name(_name) {
        this._name = _name;
    }
});

此外,它还允许您轻松创建不可枚举,不可删除和常量的属性。阅读文档以获取更多详细信息。

如果您不想要这些附加功能,请使用:

Object.prototype.define = function (properties) {
    if (Object.isExtensible(this)) {
        var ownDescriptor = Object.getOwnPropertyDescriptor;
        var defineProperty = Object.defineProperty;
        var keys = Object.keys(properties);
        var length = keys.length;
        var index = 0;

        while (index < length) {
            var key = keys[index++];
            var descriptor = ownDescriptor(properties, key);
            defineProperty(this, key, descriptor);
        }
    }
};

希望有所帮助。