5

假设我在一个名为的文件中有这样的东西main.js

function obj_name() {}

obj_name.prototype = {
    foo  : function() { alert('hi!'); },
    foo2 : function() { alert('hi again!'); }
}

现在我正在尝试这种方式来扩展另一个文件中的对象extend.js

obj_name.prototype = {
    newfoo : function() { alert('hi #3'); }
}

...但问题是,如果我这样编码,它就会起作用:

obj_name.prototype.newfoo = function() { alert('hi #3'); }

我想这可能是一个菜鸟问题。我什至不知道这是否是扩展对象的正确方法,但我在这里吓坏了,想知道为什么会发生这种情况。

提前谢谢你们。

4

4 回答 4

7

没有 jQuery 的另一个选项:

var extend = function(destination, source)
{
    for (var property in source)
    {
        if (destination[property] && (typeof(destination[property]) == 'object')
                && (destination[property].toString() == '[object Object]') && source[property])
            extend(destination[property], source[property]);
        else
            destination[property] = source[property];
    }
    return destination;
}

var a = {a: 'test'};                              // original
var b = {newFoo: function() { alert('hi #3'); }}; // the addition
extend(a, b);                                 // extend it
a.newFoo();                                   // call the added property
于 2011-05-12T08:56:27.180 回答
5

这是因为在行

obj_name.prototype = {
    newfoo : function() { alert('hi #3'); }
}

您创建一个新的原型对象,删除私有内容。好像你说过

var a = {};

当你扩展对象时

obj_name.prototype.newfoo = function() { alert('hi #3'); }

它只是向对象树添加一个新属性(newfoo),保持现有内容不变。这就是它起作用的原因

高温高压

伊沃·斯托伊科夫

于 2011-05-12T08:53:12.683 回答
4

在第一种方式中,您正在用新的原型替换原型(覆盖之前的原型)。在第二种方式中,您正在向原型添加一个新成员(从而扩展它)。

还有另一种方法:具有extend方法或类似方法的库(它基本上将您在第二种形式中所做的事情包装在一个很好的包装器中)。例如,在jQuery中:

$.extend(obj_name.prototype, {
    newfoo : function() { alert('hi #3'); }
}
于 2011-05-12T08:39:47.803 回答
1

如果您正在寻找一个简单的轻量级库,它可以准确地为您提供:OOP 在 javascript 中“正确完成”,请查看:https ://github.com/haroldiedema/joii

github页面上的自述文件中提供的源代码示例,以及这些链接:

该库基本上允许您这样定义“类”:

var Person = Class(function() {
    this.firstname = "John"
    this.surname   = "Smith"
    this.role= "Developer"

    this.getInfo = function() {
        return this.firstname + ' ' + this.surname + ' is ' + this.role;
    };
});

var AnotherPerson = Class({ extends: Person }, function() {
    this.firstname = "Bob";
});

var p = new AnotherPerson();
console.log(p.getInfo());
// Bob Smith is Developer

编辑

以您的代码为例,但转换为兼容 JOII 的代码,它看起来完全像这样:

var obj_name = Class(function() {
    this.foo = function() { alert('hi!'); };
    this.foo2 = function() { alert('hi again!'); };
};

var obj_name2 = Class({ extends: obj_name }, function() {
    this.newfoo = function() { alert('hi #3'); };
});

var o = new obj_name2();
o.foo(); // hi!
o.newfoo(); // hi #3

或将其用作混合:

var o = new obj_name();
o.mixin(obj_name2);

o.newfoo(); // hi #3

或者反过来,使用“特征”。

// the "uses" option basically copies content from the given object to the scope of your "class", solving the horizontal code-reuse problem.
var obj_name = Class({ uses: [obj_name2], function() {
    this.foo = function() { alert('hi!'); };
    this.foo2 = function() { alert('hi again!'); };
});

var o = new obj_name();
o.newfoo(); // hi #3
于 2014-04-16T17:27:44.790 回答