使用Object.create()复制构造函数和new

时间:2013-08-28 07:19:10

标签: javascript oop

根据我对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' } } );

1 个答案:

答案 0 :(得分:6)

  

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

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

  

我的理解是goat将继承/引用Animal的功能。

不完全。在new Animal表达式中,goat被赋予Animal.prototype引用的对象作为其基础原型。 Animal没有直接连接,只有Animal.prototype。 (Animal.prototype在正常情况下通过其Animal属性返回constructor的引用,但如果有人将新对象分配给Animal.prototype,该链接可能会被破坏。)

  

这里的Animal遗产是丢失的,还是Goat仍然引用Animal的方法?

在非构造函数示例中,goat获取Animal作为其基础原型,因此对于goat本身未找到的任何属性,JavaScript引擎将查看{{1}查看 it 是否拥有它。在您的示例中,这意味着Animal正在使用goat中的sayHello,而不是Animal,因为type拥有自己的goat。< / p>

粗略相当于:

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)

...然后是的,有两个问题:

  1. 您为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' ); 的每次调用都会创建一个 animalPrototype,这会使目的失效,而createAnimal会调用this 1}}将是全局对象(松散模式)或createAnimal(严格模式),因此undefined可能不是您想要的表达式。
  2. 你可以这样做:

    this.animalPrototype

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