如何使用ES5 Object.create和对象文字语法模拟构造函数?

时间:2011-01-31 20:09:01

标签: javascript object-create

假设我有一个这样的对象:

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

问题:我想用正确的src初始化该sprite。但是,当我使用以下创建技术时:

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 个答案:

答案 0 :(得分:6)

我做的事情和你上面写的非常类似,但我将它与模块模式结合起来:

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()的错误,失败

答案 1 :(得分:4)

正如我可以从这个link中假设你应该做的事情:

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

Object.create(Foo, {sprite: {value: ImgInstance("url")}});

答案 2 :(得分:1)

答案 3 :(得分:0)

我会这样做:

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

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

答案 4 :(得分:-10)

简而言之:不要试试。 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