开发者

Should I be using object literals or constructor functions?

I am getting confused over which way I should be creating an object in javascript. It seems there are 开发者_如何学JAVAat least two ways. One is to use object literal notation while the other uses construction functions. Is there an advantage of one over the other?


If you don't have behaviour associated with an object (i.e. if the object is just a container for data/state), I would use an object literal.

var data = {
    foo: 42,
    bar: 43
};

Apply the KISS principle. If you don't need anything beyond a simple container of data, go with a simple literal.

If you want to add behaviour to your object, you can go with a constructor and add methods to the object during construction or give your class a prototype.

function MyData(foo, bar) {
    this.foo = foo;
    this.bar = bar;

    this.verify = function () {
        return this.foo === this.bar;
    };
}

// or:
MyData.prototype.verify = function () {
    return this.foo === this.bar;
};

A class like this also acts like a schema for your data object: You now have some sort of contract (through the constructor) what properties the object initializes/contains. A free literal is just an amorphous blob of data.

You might as well have an external verify function that acts on a plain old data object:

var data = {
    foo: 42,
    bar: 43
};

function verify(data) {
    return data.foo === data.bar;
}

However, this is not favorable with regards to encapsulation: Ideally, all the data + behaviour associated with an entity should live together.


It essentially boils down to if you need multiple instances of your object or not; object defined with a constructor lets you have multiple instances of that object. Object literals are basically singletons with variables/methods that are all public.

// define the objects:
var objLit = {
  x: 0,
  y: 0,
  z: 0,
  add: function () {
    return this.x + this.y + this.z;
  }
};

var ObjCon = function(_x, _y, _z) {
  var x = _x; // private
  var y = _y; // private
  this.z = _z; // public
  this.add = function () {
    return x + y + this.z; // note x, y doesn't need this.
  };
};

// use the objects:
objLit.x = 3; 
objLit.y = 2; 
objLit.z = 1; 
console.log(objLit.add());    

var objConIntance = new ObjCon(5,4,3); // instantiate an objCon
console.log(objConIntance.add());
console.log((new ObjCon(7,8,9)).add()); // another instance of objCon
console.log(objConIntance.add()); // same result, not affected by previous line


Another way to create objects in a uniform way is to use a function that returns an object:

function makeObject() {
    var that = {
        thisIsPublic: "a public variable"
        thisIsAlsoPublic: function () {
            alert(that.thisIsPublic);
        }
    };

    var secret = "this is a private variable"

    function secretFunction() { // private method
        secret += "!"; // can manipulate private variables
        that.thisIsPublic = "foo";     
    }

    that.publicMethod = function () {
        secret += "?"; // this method can also mess with private variables
    }

    that.anotherPublicVariable = "baz";

    return that; // this is the object we've constructed
}

makeObject.static = "This can be used to add a static varaible/method";

var bar = makeObject();
bar.publicMethod(); // ok
alert(bar.thisIsPublic); // ok
bar.secretFunction(); // error!
bar.secret // error!

Since functions in JavaScript are closures we can use private variables and methods and avoid new.

From http://javascript.crockford.com/private.html on private variables in JavaScript.


The code below shows three methods of creating an object, Object Literal syntax, a Function Constructor and Object.create(). Object literal syntax simply creates and object on the fly and as such its __prototype__ is the Object object and it will have access to all the properties and methods of Object. Strictly from a design pattern perspective a simple Object literal should be used to store a single instance of data.

The function constructor has a special property named .prototype. This property will become the __prototype__ of any objects created by the function constructor. All properties and methods added to the .prototype property of a function constructor will be available to all objects it creates. A constructor should be used if you require multiple instances of the data or require behavior from your object. Note the function constructor is also best used when you want to simulate a private/public development pattern. Remember to put all shared methods on the .prototype so they wont be created in each object instance.

Creating objects with Object.create() utilizes an object literal as a __prototype__ for the objects created by this method. All properties and methods added to the object literal will be available to all objects created from it through true prototypal inheritance. This is my preferred method.

//Object Example

//Simple Object Literal
var mySimpleObj = {
    prop1 : "value",
    prop2 : "value"
}

// Function Constructor
function PersonObjConstr()  {
    var privateProp = "this is private";
    this.firstname = "John";
    this.lastname = "Doe";
}
PersonObjConstr.prototype.greetFullName = function()    {
    return "PersonObjConstr says: Hello " + this.firstname + 
    " " + this.lastname;
};

// Object Literal
var personObjLit = {
    firstname : "John",
    lastname: "Doe",
    greetFullName : function() {
        return "personObjLit says: Hello " + this.firstname +
        ", " + this.lastname;
    }
} 

var newVar = mySimpleObj.prop1;
var newName = new PersonObjConstr();
var newName2 = Object.create(personObjLit);


It depends on what you want to do. If you want to use (semi-)private variables or functions in you object, a constructor function is the way to do it. If your object only contains properties and methods, an object literal is fine.

function SomeConstructor(){
    var x = 5;
    this.multiply5 = function(i){
        return x*i;
    }
}
var myObj = new SomeConstructor;

var SomeLiteral = {
    multiply5: function(i){ return i*5; }
}

Now the method multiply5 in myObj and SomeLiteral do exactly the same thing. The only difference is that myObj uses a private variable. The latter may be usefull in some cases. Most of the times an Object literal is sufficient and a nice and clean way to create a JS-object.


Should I be using object literals or constructor functions?

Do you want single instance of the object for the page -- Literal.

Do you want to just transfer data like DTO objects simple GET SET :- Literal

Do you want to create real objects with method behaviors , multiple instances - Constructor function , Follow OOP principles , inheritance :- Constructor functions.

Below is the youtube video which explains in detail what is literal , what are constructor functions and how they differ from each other.

https://www.youtube.com/watch?v=dVoAq2D3n44


As mentioned in https://www.w3schools.com/js/js_object_definition.asp

Using an object literal, you both define and create , one object in one statement.

Also

Object literal only create a single object. Sometimes we like to have an object type that can be used to create many objects of one type.


Go with object literal, it's more consise and expands better with the introduction of initial values.


The Object() constructor function is a bit slower and more verbose. As such, the recommended way to create new objects in JavaScript is to use literal notation

Udacity Object-Oriented JavaScript


Actually, methinks, we can have private methods in object literals. Consider code below:

var myObject = {

   publicMethod: function () {
      privateMethod1();
      privateMethod2(); 
      function privateMethod1(){
          console.log('i am privateMethod1');
      } 
      function privateMethod2(){
          console.log('i am privateMethod2');
      } 
   }

}

Matter of taste, but I prefer to use object literals where it is possible.


Here is a benchmark that shows the access time for accessing properties on literals, constructors and classes. It might take a while but it shows almost every way to access properties. To me this benchmark shows literal properties access time overall are slightly slower than class and constructor properties access time. The worst performing times are from getters and setters on an object literal. Unlike getters and setters on classes and constructors which seem to be even faster than most other access times. Benchmark: https://www.measurethat.net/Benchmarks/Show/12245/0/the-grand-dictionary-property-accessor-schema

Should I be using object literals or constructor functions?


// Object Literal and Object constructor

function MyData(foo, bar) {
        this.foo = foo;
        this.bar = bar;

    }
MyData.prototype.verify = function () {
        return this.foo === this.bar;
    };

//add property using prototype

var MD  = new MyData;//true.
var MD = new MyData();//true.
MD.verify// return only the function structure.
MD.verify(); //return the verify value and in this case return true coz both value is null. 
var MD1  = new MyData(1,2); // intialized the value at the starting. 
MD1.verify// return only the function structure.
MD1.verify(); // return false coz both value are not same.
MD1.verify(3,3);// return false coz this will not check this value intialized at the top 
MyData.prototype.verify = function (foo,bar) {
    return this.foo === this.bar;
};
var MD1  = new MyData(1,2);
MD1.verify();
MD1.verify(3,3);// return false coz this keyword used with foo and bar that will check parent data 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜