将Javascript getters/setter复制到另一个原型对象

Ben*_*ing 8 javascript getter setter extending prototype-programming

// Base class
var Base = function() {
    this._value = 'base';
};
Base.prototype = {
    constructor: Base,
    // By function
    getValue: function() {
        return this._value;
    },
    // By getter
    get value() {
        return this._value;
    }
};

// Sub class extends Base
var Sub = function() {
    this._value = 'sub';
};
Sub.prototype = {
    constructor: Sub
};
// Pass over methods
Sub.prototype.getValue = Base.prototype.getValue;
Sub.prototype.value = Base.prototype.value;

// ---

var mySub = new Sub();
alert(mySub.getValue()); // Returns 'sub'
alert(mySub.value);      // Returns 'undefined'
Run Code Online (Sandbox Code Playgroud)

乍一看似乎mySub.value应该返回与mySub.getValue()相同的内容,但正如您所看到的那样,它返回undefined.显然,getter没有找到父作用域作为Sub实例(mySub),而是一个不存在的Base实例.

除了必须将相同的吸气剂分配到新原型之外,还有什么方法吗?

McK*_*yla 11

Sub.prototype.__defineGetter__('value', Base.prototype.__lookupGetter__('value'));
Run Code Online (Sandbox Code Playgroud)

试试吧.

  • __defineGetter__是非标准的,不符合ECMA-262标准.还有另一种方法吗? (9认同)
  • @TylerCrompton:Object.defineProperty(Sub,'value',Object.getOwnPropertyDescriptor(Base,'value')); (2认同)

Sau*_*ode 9

更现代的解决方案是使用,Object.defineProperty因为它允许处理吸气剂和设定器而不会破坏它们.

唯一的问题是它需要一个描述符对象,而不是手动使用该Object.getOwnPropertyDescriptor函数来为您获取它.

var BazValue = Object.getOwnPropertyDescriptor(Base.prototype,'value');

Object.defineProperty(Sub.prototype,'value',BazValue);
Run Code Online (Sandbox Code Playgroud)

  • 这应该是今天接受的答案.然而`defineProperty` /`getOwnPropertyDescriptor`来自ECMAscript 5.1,它是在2011年6月定义的,在[当前接受的答案]之后一个月(/sf/answers/422779591/) (2认同)

Ale*_*Mcp 5

我认为如果你分配了它会有用

Sub.prototype = new Base()
Run Code Online (Sandbox Code Playgroud)

问题是,当您从Base.prototype.value直接分配构造函数时,它永远不会运行.在拥有Base类的实例(via new)之前,该值将不存在

这是我扩展Function实现继承的典型方法:

Function.prototype.Extend = function(superClass) {
    this.prototype = new superClass();

    this.prototype.getSuperClass = function() {
        return superClass;
    };
    this.getSuperClass = this.prototype.getSuperClass;
    return this;
};
Run Code Online (Sandbox Code Playgroud)

这将正确地将所有父类方法和属性分配给子"类".

用法看起来像

var Sub = function() {}
Sub.Extend(Base)
Run Code Online (Sandbox Code Playgroud)