Я не понимаю, каким образом я должен создавать объект в javascript. Кажется, есть как минимум два пути. Один из них - использовать буквальную нотацию объекта, а другой - функции построения. Есть ли у одного преимущество перед другим?
Я не понимаю, каким образом я должен создавать объект в javascript. Кажется, есть как минимум два пути. Один из них - использовать буквальную нотацию объекта, а другой - функции построения. Есть ли у одного преимущество перед другим?
Ответы:
Если у вас нет поведения, связанного с объектом (т.е. если объект является просто контейнером для данных / состояния), я бы использовал литерал объекта.
var data = {
foo: 42,
bar: 43
};
Примените принцип KISS . Если вам не нужно ничего, кроме простого контейнера данных, используйте простой литерал.
Если вы хотите добавить поведение к своему объекту, вы можете использовать конструктор и добавить методы к объекту во время построения или дать своему классу прототип.
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;
}
Однако это неблагоприятно для инкапсуляции: в идеале все данные + поведение, связанные с сущностью, должны существовать вместе.
this.fn = function ...подход в конструкторе, каждый из ваших экземпляров объекта будет иметь свои собственные копии функций. Используя подход прототипа, вы присоединяете каждую функцию один раз и только один раз: они будут унаследованы экземплярами через прототипное наследование.
По сути, это сводится к тому, нужно ли вам несколько экземпляров вашего объекта или нет; объект, определенный с помощью конструктора, позволяет иметь несколько экземпляров этого объекта. Объектные литералы - это, по сути, синглтоны с общедоступными переменными / методами.
// 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);
Object.createфункцию внутри литерала, он будет уникальным для каждого экземпляра?
Это зависит от того, чем вы хотите заниматься. Если вы хотите использовать (полу) частные переменные или функции в своем объекте, функция-конструктор - это способ сделать это. Если ваш объект содержит только свойства и методы, подойдет литерал объекта.
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в myObjиSomeLiteral делать то же самое. Единственное отличие в том, что myObj использует частную переменную. Последнее может быть полезно в некоторых случаях. В большинстве случаев литерала объекта достаточно, и это хороший и чистый способ создания JS-объекта.
Вам нужен единственный экземпляр объекта для страницы - Literal.
Вы хотите просто передавать данные, такие как объекты DTO, просто GET SET: - Literal
Вы хотите создавать реальные объекты с поведением методов, несколько экземпляров - функция конструктора, следование принципам ООП, наследование: - функции конструктора.
Ниже приведено видео на YouTube, в котором подробно объясняется, что такое буквальное, что такое функции-конструкторы и чем они отличаются друг от друга.
Используйте литерал объекта, он более понятен и лучше расширяется с введением начальных значений.
Как упоминалось в https://www.w3schools.com/js/js_object_definition.asp
С помощью литерала объекта, вы оба определить и создать , один объект в одном заявлении.
Также
Литерал объекта создает только один объект. Иногда нам нравится иметь объектный тип, который можно использовать для создания множества объектов одного типа.
Функция конструктора Object () работает немного медленнее и более подробна. Таким образом, рекомендуемый способ создания новых объектов в JavaScript - использовать буквальную нотацию
На самом деле, мне кажется, у нас могут быть частные методы в объектных литералах. Рассмотрим код ниже:
var myObject = {
publicMethod: function () {
privateMethod1();
privateMethod2();
function privateMethod1(){
console.log('i am privateMethod1');
}
function privateMethod2(){
console.log('i am privateMethod2');
}
}
}
Дело вкуса, но я предпочитаю использовать объектные литералы там, где это возможно.
// Литерал объекта и конструктор объекта
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