2

根据我对 OOP javascript 的有限经验,处理具有不同属性但相同方法的多个对象的常用方法是使用如下构造函数:

function Animal ( type ) {
    this.type = type
};
Animal.prototype.sayHello = function () {
    return 'Hi, I am a ' + this.type
};
var goat = new Animal( 'Goat' );

我的理解是goat继承/引用Animal.

我想可以使用以下对象文字概念复制上述内容:

var Animal = {
    type : '',
    sayHello : function () {
        return 'Hi, I am a ' + this.type
    }
}
var goat = Object.create( Animal );
goat.type = 'Goat';

继承在Animal这里丢失了,还是Goat仍在引用Animal方法?

我想知道使用Object.create()而不是new复制构造函数/类是否有任何问题。是否有性能偏移或任何理由继续使用new

任何建议将不胜感激,如果需要澄清,我很乐意补充问题。

更新对象创建

var Animal = {
    sayHello : function () {
        return 'Hi, I am a ' + this.type
    }
}
var goat = Object.create( Animal, { 'type' : { value: 'goat' } } );
4

1 回答 1

6

...处理具有不同属性但相同方法的多个对象的常用方法是使用构造函数...

是的,另一种常见的方式是(如您所见)Object.create

我的理解是goat继承/引用Animal.

不完全的。在new Animal表达式中,goat将被分配的对象Animal.prototype作为其底层原型。与 没有直接联系Animal,只是与Animal.prototype。(在正常情况下,通过其属性Animal.prototype有一个引用,尽管如果有人将新对象分配给该链接可能会被破坏。)AnimalconstructorAnimal.prototype

继承在Animal这里丢失了,还是Goat仍在引用Animal方法?

在您的非构造函数示例中,goatgetsAnimal作为其底层原型,因此对于goat自身未找到的任何属性,JavaScript 引擎将查看Animal是否具有它。在您的示例中,这意味着goat使用sayHellofrom Animal,但不是type,因为goat有自己的type

大致相当于:

function Animal ( type ) {
    this.type = type
};
Animal.prototype.sayHello = function () {
    return 'Hi, I am a ' + this.type
};
var goat = new Animal( 'Goat' );

...Object.create用于设置原型,而不是如下所示:

var animalPrototype = {
    sayHello: function () {
        return 'Hi, I am a ' + this.type
    }
};
function createAnimal(type) {
    var rv = Object.create(animalPrototype);
    rv.type = type;
    return rv;
};
var goat = createAnimal( 'Goat' );

回复您的评论:

会不会有任何问题,包括animalPrototype里面createAnimal然后打电话Object.create(this.animalPrototype)

如果你是这个意思:

function createAnimal(type) {
    var animalPrototype = {                       // Issue #1
        sayHello: function () {
            return 'Hi, I am a ' + this.type
        }
    };
    var rv = Object.create(this.animalPrototype); // Issue #2
    rv.type = type;
    return rv;
};
var goat = createAnimal( 'Goat' );

...那么是的,有两个问题:

  1. 你会为每次调用创建一个 的,这违背了目的,并且 2.在调用中将是全局对象(松散模式)或(严格模式),所以可能不是你想要的表达式。animalPrototypecreateAnimalthiscreateAnimalundefinedthis.animalPrototype

你可以这样做:

function createAnimal(type) {
    var rv = Object.create(createAnimal.proto);
    rv.type = type;
    return rv;
};
createAnimal.proto = {
    sayHello: function () {
        return 'Hi, I am a ' + this.type
    }
};
var goat = createAnimal( 'Goat' );

当然,这可能会让人们感到困惑,因为它看起来很像构造函数。

于 2013-08-28T07:21:48.230 回答