【问题标题】:Javascript class inheritance w/ both this._super and proper defineProperty descriptors带有 this._super 和正确的 defineProperty 描述符的 Javascript 类继承
【发布时间】:2014-08-29 00:41:58
【问题描述】:

我真的很喜欢John Resig's simple inheritance method。它有很好的语法,而且 this._super 非常强大。

2014 年很艰难,我希望能够定义 getter 和 setter 以及其他描述符(但尽可能保持 Resig 版本的简单性)。

在保持类似于我非常珍视的 Resig 的语法的同时,我将如何解决这个问题?

我的梦想是这样的:

var Person = Class.extend({
  init: function(isDancing){
    this.dancing = isDancing;
  },
  dance: function(){
    return this.dancing;
  }
  tools: {                    // <---- this would be so awesome
     get: function() { ... },
     set: function(v) { ... },
     enumerable: true
  },
});

var Ninja = Person.extend({
  init: function(){
    this._super( false );
  },
  dance: function(){
    // Call the inherited version of dance()
    return this._super();
  },
  swingSword: function(){
    return true;
  },
  tools: {
     get: _super,           //  <---- and this too
     set: function(v) {
        this._super(v);
        doSomethingElse();
     }
  }
});

【问题讨论】:

  • 继承永远不是答案!尤其是在 javascript 中。

标签: javascript oop inheritance getter-setter prototypal-inheritance


【解决方案1】:

我不知道您为什么要这样做,因为您可以通过 JavaScript 对象的性质轻松绕过这一点,但我喜欢您问题的精神。

与其在你的类中定义方法,我想为什么不为所有类定义它呢?在 eJohn 的代码中,我在他将原型声明为变量之后立即添加了两个函数。 StackOverflow 有点长,请查看this cool pen I made 以获得更清晰的示例。

...// Instantiate a base class (but only create the instance,
// don't run the init constructor)
initializing = true;
var prototype = new this();
initializing = false;

prototype.set = function (attr, val) {
  return this[attr] = val;
}

prototype.get = function (attr) {
  return this[attr];
}

// Copy the properties over onto the new prototype ...

然后您的课程将如下所示:

var Person = Class.extend({
  init: function(isDancing){
    this.dancing = isDancing;
  },
  dance: function(){
    return this.dancing;
  }
});

var Ninja = Person.extend({
  init: function(){
    this._super( false );
  },
  dance: function(){
    // Call the inherited version of dance()
    return this._super();
  },
  swingSword: function(){
    return true;
  },
  set: function (attr, val) {
    this._super(attr, val);
    console.log('doing other things');
  }
});

所以你可以这样做:

var p = new Person(true);

p.get('dancing');        // => true
p.set('dancing', false); // Telling the person to please stop dancing (he's drunk)
p.dance();               // => false... "whew!"
p.get('dancing')         // => false - he must be asleep

var n = new Ninja();

n.get('dancing');       // => false, ninjas don't dance
n.set('dancing', true); // except my ninjas do
n.get('dancing');       // => true, cause they're rad

【讨论】:

  • 这太棒了,但它不使用原生 ECMAScript5 描述符。我认为解决这个问题的真正方法(阅读:hacky)是编辑属性克隆函数以检查是否存在值、获取或设置键,然后将其通过管道传递给 Object.defineProperty。也许。我不知道这是否可行。去测试一下。
猜你喜欢
  • 1970-01-01
  • 2017-11-30
  • 1970-01-01
  • 2020-06-06
  • 1970-01-01
  • 1970-01-01
  • 2010-09-19
  • 1970-01-01
  • 2018-06-01
相关资源
最近更新 更多