使用Object.create()的正确方法

时间:2014-07-05 18:50:40

标签: javascript ecmascript-5 ecmascript-6

学习Javascript我发现了创建对象的不同方法。似乎前进的方向是使用Object.create()

很难找到关于使用Object.create()的最佳做法的可靠答案,因为即使特定的Object.create()文章似乎也会略有不同。

我想要做的是使用自己的封装数据创建多个对象。

我喜欢使用封装,似乎对我有用的东西就像是

function Foo() {
    var message = "Hello";

    return {
        bar:bar
    }

    function bar(){ 
        return message; 
    }
}

World = (function(){ 
    var obj = Foo();
    var tank = Object.create(obj);

    return {
        baz:baz
    }

    function baz(){ 
        alert(tank.bar()); 
    }

})();

正在运行World.baz()按预期工作,但我仍然不确定我是否正确行事。

所有答案将不胜感激,谢谢。

3 个答案:

答案 0 :(得分:1)

通常在javascript中你想创建像这样的对象:

var obj = {};
obj.someProperty = 'someValue';
obj.someOtherProperty = 'someOtherValue';

或者,您可以使用对象文字表示法,如下所示:

var obj = {
    someProperty: 'someValue',
    someOtherProperty: 'someOtherValue'
};

Object.create函数很有意思。是的,它确实创建了一个空对象,但它不像上面定义的对象。使用Object.create实例化和对象将为您提供Object.create函数的参数提供新的空对象继承。例如,如果我们将对象定义为:

var actions = {
    shout: function(message){
        console.log(message.toUpperCase() + '!');
    }
}

然后使用Object.create()创建一个新对象:

var newObject = Object.create(actions);  // creates a new object: newObject = {};

newObject将不包含任何属性,但它将能够访问父操作对象的属性。在定义了这些对象之后,试试这个:

newObject.hasOwnProperty('shout');    // returns false
newObject.shout('Hello!');    // logs 'HELLO!!'

这个例子只是展示了继承如何从新创建的对象到它的父对象。这可能非常有用,但请确保在使用Object.create创建对象之前特别需要该行为 - 否则,最好是安全并使用上述其他两种方法之一。

希望有所帮助!

编辑:

或者,如果您只是尝试创建同一对象的许多单独实例,则可以创建构造函数并使用new关键字调用它,如下所示:

var Tank = function(speed, durability){
    this.speed = speed;
    this.durability = durability;
    this.location = 0;
    this.shoot = function(){
        console.log('Pew pew');
    };
    this.move = function(){
        this.location += speed;
    };
}

var myTank = new Tank(5, 15);    // creates new tank with speed 5 and durability 15,
                                 // that also has all the default properties and methods,
                                 // like location, shoot, and move.

var yourTank = new Tank(7, 12);  // instantiates a different tank that myTank, with it's
                                 // own speed and durability properties, but also has the
                                 // default location, shoot, and move properties/ methods

var enemyTank = new Tank(10, 25);// instantiates yet another, unique tank with it's own 
                                 // unique values for speed and durability, but again with
                                 // the default location, shoot, and move properties/methods

答案 1 :(得分:0)

我建议使用构造函数来封装数据。如果确实需要使用Object.create(),则需要使用Object.create()创建构造函数原型系统。但是,无论如何,您只需.bar() Foo() .baz()方法中World的结果调用World。这并不意味着Foo()应该指向Object.prototype.__construct = function() { //This is the default constructor from any new object. We change it to change the constructor of objects as we go along. We could make no __construct method on Object.prototype because it doesn't do anything, so we're not going to call it, but we're going to define it anyway since we want all objects to have a __construct method, even if they don't define a new one on top of the default. }; //Object.prototype is our default object. We add methods to object to change the prototype of objects as we go along. var Foo = {}; //Any object that doesn't inherit from anything must inherit from Object.prototype. We do this by just setting it to {} (or new Object()). //If we're going to define a new constructor, we need to call it _after_ we've defined it. Foo.__construct = function() { var message = "Hello!"; this.bar = function() { return message; } }; Foo.__construct(); Foo.bar() //returns "Hello!" //Note that message is encapsulated and _cannot_ be accessed through Foo itself. var World = {}; //World _does not_ point to Foo. It simply calls a method of Foo in one of its methods. World.__construct = function() { //Now, if the method of Foo we're going to call in the method of World is going to alter Foo, then we should make a copy of Foo using Object.create(). The method we're going to call isn't _actually_ going to alter Foo, but it's good practice to make a copy because it _could_ if we made it so. var obj = Object.create(Foo); //Because Foo has been constructed and obj is a copy of Foo, we don't need to construct obj. We only need to construct an object if we define a new constructor property. this.baz = function() { alert(obj.bar()); }; }; World.__construct(); World.baz() //alerts "Hello!" //Note that obj is encapsulated within World. obj points to Foo, but again, World _does not_ point to Foo. 的结果。

{{1}}

答案 2 :(得分:0)

尝试使用此方法创建封装数据的javaScript对象。正如您所看到的,Foo的每个实例都有自己的属性和状态。

    var Foo = function() {

        var Foo = function Foo(customMessage) {
            this.message = customMessage || "Hello";
        }

        Foo.prototype.message;

        Foo.prototype.bar = function(){ 
            return this.message; 
        }

        return Foo;
    }();

    var tank1 = new Foo();
    var tank2 = new Foo("Goodbye");

    alert(tank1.bar());
    alert(tank2.bar());