Как эмулировать конструктор с ES5 Object.create и литералом синтаксиса объекта? - PullRequest
5 голосов
/ 31 января 2011

Предположим, у меня есть такой объект:

var Foo = {
  x: 5,
  sprite: new Image()
}

Проблема: я хочу инициализировать этот спрайт с правильным src. Однако, когда я использую следующую технику создания:

var f = Object.create(Foo);

У меня нет метода конструктора (он же init-функция) для настройки sprite.src = 'cool.png';

Мой вопрос:

Если я использую технику объектного литерала, и Object.create(), когда я на самом деле инициализирую часть своего внутреннего состояния (например, пример new Image())

Мое решение:

var Foo = {
  create: function() {
    var f = Object.create(Foo);
    f.sprite.src = 'cool.png';
    return f;
  }
}

Однако я не знаю, является ли это отличным примером. Я хотел бы сделать это "Путь JavaScript", если есть способ. :)

Спасибо!

Ответы [ 5 ]

6 голосов
/ 05 апреля 2011

Я делаю что-то очень похожее на то, что вы написали выше, но я комбинирую это с шаблоном модуля:

var Vehicle = (function(){
        var exports = {};
        exports.prototype = {};
        exports.prototype.init = function() {
                this.mph = 5;
        };
        exports.prototype.go = function() {
                console.log("Going " + this.mph.toString() + " mph.");
        };

        exports.create = function() {
                var ret = Object.create(exports.prototype);
                ret.init();
                return ret;
        };

        return exports;
})();

Снаружи это выставляет Vehicle.create() и Vehicle.prototype.Затем, если я хочу создать производный тип, я могу сделать это:

var Car = (function () {
        var exports = {};
        exports.prototype = Object.create(Vehicle.prototype);
        exports.prototype.init = function() {
                Vehicle.prototype.init.apply(this, arguments);
                this.wheels = 4;
        };

        exports.create = function() {
                var ret = Object.create(exports.prototype);
                ret.init();
                return ret;
        };

        return exports; 

})();

Этот шаблон позволяет мне получать типы без ошибки Car.prototype = new Vehicle(), которая равна fail , если мойконструкторы принимают параметры.

4 голосов
/ 01 февраля 2011

Как я могу предположить из этой ссылки , вы должны сделать что-то вроде:

function ImgInstance(src){
    var img=new Image();
    img.src=src;
    return img;
}

Object.create(Foo, {sprite: {value: ImgInstance("url")}});
1 голос
/ 08 февраля 2013

Я думаю, что эта статья довольно хорошо подводит итог:

http://www.bennadel.com/blog/2184-Object-create-Improves-Constructor-Based-Inheritance-In-Javascript-It-Doesn-t-Replace-It.htm

0 голосов
/ 01 февраля 2011

Короче говоря, не пытайтесь.Основная идея Object.create - избегать функций конструктора.Вам лучше использовать этот старый добрый шаблон:

var Foo = function (url) {
    //this.sprite.src = url; //  This will overwrite the prototype's src
    this.sprite = new Image();
    this.sprite.src = url;
};
Foo.prototype = {
    x: 5,
    sprite: new Image() // do you really want this?
};

Тогда используйте new Foo вместо Object.create.

0 голосов
/ 31 января 2011

Я бы просто сделал это:

function Image(src) {
    this.src = src;
}

function Foo() {
    this.x = 5;
    this.sprite = new Image('cool.png');
}
...