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

mik*_*his 2 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' );
Run Code Online (Sandbox Code Playgroud)

我在这里的理解是goat继承/引用函数Animal.

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

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

继承在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' } } );
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 6

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

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

我在这里的理解是goat继承/引用函数Animal.

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

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

在您的非构造例如,goat获得Animal作为其基础的原型,所以在没有找到任何财产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' );
Run Code Online (Sandbox Code Playgroud)

... 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' );
Run Code Online (Sandbox Code Playgroud)

你的评论:

会有任何问题,包括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' );
Run Code Online (Sandbox Code Playgroud)

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

  1. 你为每次调用创建了一个 animalPrototypecreateAnimal,这会破坏目的,并且2. this在调用createAnimal中将要么是全局对象(松散模式)还是undefined(严格模式),所以this.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' );
Run Code Online (Sandbox Code Playgroud)

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

  • +1非常好,客观地总结了正在发生的事情.OP - 单词__Yes__,使用`Object.create`可以让你在JavaScript中进行原型继承.它创建一个新对象,其_prototype_是您指定的对象.(顺便说一下,我喜欢'喜欢Object.create大多数情况') (2认同)
  • @BenjaminGruenbaum:谢谢!我采取了相当平衡的观点.如果我正在创造一些感觉"优雅"的东西,我会使用构造函数(通过我的[Lineage脚本](http://code.google.com/p/lineagejs/)).但我总是使用`Object.create`,我只需要一个与另一个特定对象大致相同但略有不同的对象.我有一个项目,我们做了很多,虽然*可以*使用构造函数完成,但它会非常笨重.我发现它们都是非常有用的工具.我喜欢JavaScript的灵活性. (2认同)