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

Set*_*add 5 javascript object-create

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

var Foo = {
  x: 5,
  sprite: new Image()
}
Run Code Online (Sandbox Code Playgroud)

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

var f = Object.create(Foo);
Run Code Online (Sandbox Code Playgroud)

我没有构造方法(也就是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;
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,我不知道这是否是一个很好的模式.如果有办法,我想做"JavaScript方式".:)

谢谢!

Sea*_*lan 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;
})();
Run Code Online (Sandbox Code Playgroud)

从外面看,这暴露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; 

})();
Run Code Online (Sandbox Code Playgroud)

这种模式让我可以在不产生错误的情况下派生类型Car.prototype = new Vehicle(),如果构造函数采用参数,则会失败.


use*_*621 -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?
};
Run Code Online (Sandbox Code Playgroud)

然后使用new Foo代替Object.create.