简体   繁体   English

具有this._super和适当的defineProperty描述符的Javascript类继承

[英]Javascript class inheritance w/ both this._super and proper defineProperty descriptors

I really grok with John Resig's simple inheritance method . 我真的很讨厌John Resig的简单继承方法 It has nice syntax and the this._super is super powerful. 它具有不错的语法,this._super非常强大。

It's 2014 tough, and I want to be able to define getters & setters along with other descriptors (but still maintain the simplicity of the Resig version if possible). 2014年艰难,我希望能够定义getter和setter以及其他描述符(但如果可能的话,仍要保持Resig版本的简单性)。

How would I got about that while keeping the syntax akin to Resig's that I hold so dear? 在保持类似于我所珍视的Resig的语法的同时,我将如何处理?

My dream is something like this: 我的梦想是这样的:

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();
     }
  }
});

I don't know why you'd want to do this since you could easily circumvent this by the nature of JavaScript objects, but I liked the spirit of your question. 我不知道您为什么要这样做,因为您可以通过JavaScript对象的性质轻松地绕开它,但是我喜欢您提出问题的精髓。

Rather than define the method in your class, I figured why not define it for all classes? 而不是在您的类中定义方法,我想到了为什么不为所有类都定义它? In eJohn's code I added two functions right after he declares prototype as a variable. 在eJohn的代码中,我在将prototype声明为变量之后立即添加了两个函数。 It's a bit long for StackOverflow so please check out this cool pen I made for a more clear example. StackOverflow有点长,所以请查看我制作的这款炫酷笔,以获得更清晰的示例。

...// 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 ...

And then your classes would look like this: 然后您的类将如下所示:

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');
  }
});

So you can do stuff like this: 因此,您可以执行以下操作:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM