使用extend()和include()函数向类添加属性

时间:2012-11-02 04:03:46

标签: oop javascript javascript-framework

有人可以向我解释以下代码中发生了什么吗?我理解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();

3 个答案:

答案 0 :(得分:1)

他是从Javascript Web Applications by Alex MacCaw得到的。目的是演示实现Javascript类,并使用适当的模块化和继承。作者在他的解释中非常抽象,并没有说明是否使用了诸如Prototype.js之类的库。

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

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

答案 1 :(得分:1)

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

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

因此,如果我们在参数对象中有一个'extended'属性 - 我们称之为。

答案 2 :(得分:0)

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

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设置为function(其作业在调用时初始化'this') - 但尚未执行。 (ii)初始属性是在klass的原型上定义的; init属性被设置为一个空函数(我们将在稍后根据我们定义的类覆盖)(iii)在klass上使用extend和include属性的一些更奇特的东西(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属性上(通过apply form) - >我们刚刚覆盖了这个'init'属性。

    klass.fn.parent = klass; //我们在哪里使用它? //没有。