Должен ли я использовать объектные литералы или функции конструктора?


Я запутываюсь в том, каким образом я должен создавать объект в javascript. Кажется, есть по крайней мере два способа. Один из них-использовать объектную литеральную нотацию, а другой использует функции построения. Есть ли преимущество одного над другим?

10   82   2011-02-01 09:57:19

10 ответов:

если у вас нет поведения, связанного с объектом (т. е. если объект является просто контейнером для данных/состояния), я бы использовал литерал объекта.

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

применить принцип KISS. Если вам не нужно ничего, кроме простого контейнера данных, используйте простой литерал.

если вы хотите добавить поведение к своему объекту, вы можете пойти с конструктором и добавить методы к объекту во время строительства или дать свой класс a прототип.

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;
};

такой класс также действует как схема для вашего объекта данных: теперь у вас есть какой-то контракт (через конструктор), какие свойства объект инициализирует/содержит. Свободный литерал - это просто аморфный сгусток данных.

вы могли бы также иметь внешнюю verify функция, которая действует на простой старый объект данных:

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

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

однако это не является благоприятным в отношении инкапсуляции: в идеале, все данные + поведение связанные с сущностью должны жить вместе.

Это, по сути, сводится к тому, если вам нужно несколько экземпляров вашего объекта или нет; объект, имеющий конструктор позволяет вам иметь несколько экземпляров этого объекта. Объектные литералы в основном являются синглетами с переменными / методами, которые являются общедоступными.

// 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

другой способ создания объектов единообразным способом-использовать функцию, которая возвращает объект:

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!

поскольку функции в JavaScript являются замыканиями, мы можем использовать частные переменные и методы и избегать new.

от http://javascript.crockford.com/private.html О частных переменных в JavaScript.

в приведенном ниже коде показаны три метода создания объекта, синтаксис объектного литерала, конструктор функций и Object.create(). Объектный литеральный синтаксис просто создает и объект на лету и как таковой его __prototype__ - это Object "объект" и он будет иметь доступ ко всем свойствам и методам Object. Строго с точки зрения шаблона проектирования простой литерал объекта должен использоваться для хранения одного экземпляра данных.

конструктор функции имеет специальное свойство с именем .prototype. Это свойство станет __prototype__ любых объектов, созданных конструктором функции. Все свойства и методы добавлены в .prototype свойство конструктора функции будет доступно для всех объектов, которые он создает. Конструктор следует использовать, если требуется несколько экземпляров данных или требуется поведение объекта. Примечание конструктор функций также лучше всего использовать, когда вы хотите смоделировать частный/публичный шаблон разработки. Не забудьте поставить все общие методы .prototype таким образом, они не будут созданы в каждом экземпляре объекта.

создание объектов с Object.create() использует литерал объекта, как __prototype__ для объектов, созданных этим методом. Все свойства и методы, добавленные в литерал объекта, будут доступны всем объектам, созданным из него посредством истинного прототипного наследования. Это мой предпочтительный метод.

//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);

Это зависит от того, что вы хотите сделать. Если вы хотите использовать (полу)частные переменные или функции в вашем объекте, функция конструктора-это способ сделать это. Если ваш объект содержит только свойства и методы, литерал объекта в порядке.

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

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

теперь метод multiply5 in myObj и SomeLiteral сделать то же самое. Единственное различие заключается в том, что myObj использует закрытую переменную. Последнее может быть полезно в некоторых случаях. В большинстве случаев достаточно литерала объекта и хороший и чистый способ создать JS-объект.

enter image description here

вы хотите один экземпляр объекта для страницы -- литерал.

вы хотите просто передавать данные, такие как объекты DTO просто получить набор :- Literal

вы хотите создавать реальные объекты с поведением метода, несколькими экземплярами-функция конструктора, следовать принципам ООП, наследование: - функции конструктора.

ниже видео youtube, которое подробно объясняет, что такое буквальное, что такое функции конструктора и как они отличаются друг от друга.

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

перейти с литералом объекта, это более consise и расширяется лучше с введением начальных значений.

Как упоминалось в https://www.w3schools.com/js/js_object_definition.asp

используя литерал объекта, вы оба определение и создать,один

функция конструктора Object () немного медленнее и более подробна. Как таким образом, рекомендуемый способ создания новых объектов в JavaScript-это используйте буквенную нотацию

Udacity Объектно-Ориентированный JavaScript

// литерал объекта и конструктор объекта

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