【问题标题】:Adding properties to classes using extend() and include() functions使用 extend() 和 include() 函数向类添加属性
【发布时间】:2012-11-02 04:03:45
【问题描述】:

谁能向我解释以下代码中发生了什么?我理解 include() 和 exclude() 的含义,但是我们什么时候以及为什么要使用特定的函数呢?

var Class = function () {
    var klass = function () {
        this.init.apply(this, arguments);
    };

    klass.prototype.init = function () {};

    klass.fn = klass.prototype;
    //shortcut to access class
    klass.fn.parent = klass; //where do we use it?

    //adding class properties
    klass.extend = function (obj) {
        var extended = obj.extended; //what is happening here?
        for (var i in obj) {
            klass[i] = obj[i];
        }
        if (extended) extended(klass) //didn't understand this part
    };
    //adding instance properties
    klass.include = function (obj) {
        var included = obj.included; //??
        for (var i in obj) {
            klass.fn[i] = obj[i]; //??
        }
        if (included) included(klass) //??
    };
    return klass;
};
var Person = new Class; // is this same as: var Person = new Class();

【问题讨论】:

  • 您是从Prototype.js 获得的吗?如果您知道这段代码何时可以解决特定问题,那么掌握或理解并不是那么复杂。一个问题:What do you want this code to do?

标签: oop javascript javascript-framework


【解决方案1】:

他是从Javascript Web Applications by Alex MacCaw 那里得到的。目的是演示实现 Javascript 类,并使用适当的模块化和继承。作者的解释很抽象,并没有具体说明是否使用了Prototype.js等库。

我认为这个问题的一个很好的补充是:

  • 这一切看起来都像原生 Javascript 吗?
  • 是否扩展/扩展和包含/包含 Javascript 的本机方法?

【讨论】:

    【解决方案2】:

    在您的问题块作者给我们这部分之后:

    Person.extend({
        extended: function(klass) {
            console.log(klass, " was extended");
        }
    });
    

    因此,如果我们在参数对象中有“扩展”属性 - 我们称之为。

    【讨论】:

      【解决方案3】:

      想提供我的理解。我会将其分为两部分:定义和实现(或使用)。 按照您上面引用的定义,我将添加用法作为此代码:

      var Person = new Class;
      
      Person.extend({
          find: function(id) { /* definition */
          },
          exists: function(id) { /* definition */
          }
      });
      Person.include({
          save: function(id) { /* definition */
          },
          destroy: function(id) { /* definition */
          }
      });
      
      var person_e = Person.find(1);
      var person_e = Person.exists(2);
      
      var person = new Person;
      person.save();
      person.destroy(2);
      

      查看此代码与之前代码的连续性。 我会尝试列举发生了什么:

      1. 类设置为保存函数定义。它还没有执行——所以 Class 指向内存中写入函数定义的那个块。
      2. var Person = new Class -> 这相当于'new Class()' - 所以会执行Class,并将结果分配给Person。由于它是使用“new”关键字调用的,因此“this”被分配给 Class 的新实例。
      3. 现在,Class() 内部发生了什么? (i) klass 设置为函数(其工作是在调​​用时初始化“this”)-但尚未执行。 (ii) 在 klass 的原型上定义了一个 init 属性; init 属性设置为一个空函数(稍后我们将根据我们定义的类来覆盖它) (iii) 一些更花哨的东西,扩展并包含 klass 上的属性 (iv) 并返回 klass -> klass 在此保存函数定义时间点。因此,调用 'new Class()' 会返回一个名为 'klass' 的函数,调用该函数时会对 'this' 执行初始化。
      4. 此时的人,用外行的话来说,可以被认为是持有'function klass()'。所以,Person.extend 可以认为是去klass.extend 的部分代码。 klass.extend 是一个需要对象的函数。该对象具有键值对,键是实用程序/函数的名称,值是函数定义。在 'for' 语句中,我们执行 (var i in obj) - 所以 'i' 包含键 - 当我们执行 'klass.fn[i]' 时,我们的意思是 klass.prototype.save 或 klass.prototype.destroy - 因为下标[i] 与点表示法(命名空间)相同。我们知道,添加到 klass.prototype 的方法可用于 Person 的实例,而不是作为属性添加到 Person。
      5. 我们调用 new Person() - 实际上,我们正在执行 klass,因为此时 Person 持有 klass,并且由于附加了 new,因此传递了“this”。现在,在 'klass' 内部,初始化发生在 'this' 的 init 属性上(通过应用形式)-> 而我们刚刚覆盖的这个 'init' 属性。

        klass.fn.parent = klass; //我们在哪里使用它? //不知道在哪里。

      【讨论】:

        猜你喜欢
        • 2017-08-26
        • 2023-03-06
        • 2010-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多