Estou ficando confuso sobre como devo criar um objeto em javascript. Parece que existem pelo menos duas maneiras. Uma é usar notação literal de objeto enquanto a outra usa funções de construção. Existe uma vantagem de um sobre o outro?
Estou ficando confuso sobre como devo criar um objeto em javascript. Parece que existem pelo menos duas maneiras. Uma é usar notação literal de objeto enquanto a outra usa funções de construção. Existe uma vantagem de um sobre o outro?
Respostas:
Se você não tiver um comportamento associado a um objeto (ou seja, se o objeto for apenas um contêiner de dados / estado), eu usaria um literal de objeto.
var data = {
foo: 42,
bar: 43
};
Aplique o princípio KISS . Se você não precisa de nada além de um simples contêiner de dados, use um literal simples.
Se você deseja adicionar comportamento ao seu objeto, você pode ir com um construtor e adicionar métodos ao objeto durante a construção ou dar a sua classe um protótipo.
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;
};
Uma classe como essa também atua como um esquema para seu objeto de dados: agora você tem algum tipo de contrato (por meio do construtor) de quais propriedades o objeto inicializa / contém. Um literal livre é apenas uma bolha amorfa de dados.
Você também pode ter uma verifyfunção externa que atua em um objeto de dados simples e antigo:
var data = {
foo: 42,
bar: 43
};
function verify(data) {
return data.foo === data.bar;
}
No entanto, isso não é favorável com relação ao encapsulamento: Idealmente, todos os dados + comportamento associados a uma entidade devem viver juntos.
this.fn = function ...abordagem em um construtor, cada uma das instâncias de seu objeto terá suas próprias cópias de funções. Usando a abordagem de protótipo, você anexa cada função uma vez e apenas uma vez: elas serão herdadas pelas instâncias por meio da herança prototípica.
Basicamente, ele se resume a se você precisa ou não de várias instâncias do seu objeto; objeto definido com um construtor permite que você tenha várias instâncias desse objeto. Literais de objeto são basicamente singletons com variáveis / métodos que são todos públicos.
// 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
Outra maneira de criar objetos de maneira uniforme é usar uma função que retorna um objeto:
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!
Uma vez que as funções em JavaScript são encerramentos, podemos usar variáveis e métodos privados e evitar new.
De http://javascript.crockford.com/private.html em variáveis privadas em JavaScript.
O código abaixo mostra três métodos de criação de um objeto, sintaxe Object Literal, um Construtor de Função e Object.create(). A sintaxe literal do objeto simplesmente cria um objeto em tempo real e, como tal, __prototype__é o Objectobjeto e terá acesso a todas as propriedades e métodos deObject . Estritamente de uma perspectiva de padrão de projeto, um literal de objeto simples deve ser usado para armazenar uma única instância de dados.
O construtor da função tem uma propriedade especial chamada .prototype. Esta propriedade se tornará a __prototype__de qualquer objeto criado pelo construtor da função. Todas as propriedades e métodos adicionados à .prototypepropriedade de um construtor de função estarão disponíveis para todos os objetos que ele cria. Um construtor deve ser usado se você precisar de várias instâncias dos dados ou de comportamento do seu objeto. Observe que o construtor de função também é melhor usado quando você deseja simular um padrão de desenvolvimento privado / público. Lembre-se de colocar todos os métodos compartilhados no .prototypepara que não sejam criados em cada instância do objeto.
A criação de objetos com Object.create()utiliza um literal de objeto __prototype__para os objetos criados por este método. Todas as propriedades e métodos adicionados ao literal do objeto estarão disponíveis para todos os objetos criados a partir dele por meio da verdadeira herança prototípica. Este é o meu método preferido.
//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.createa função dentro do literal, ele será exclusivo por instância?
Depende do que você quer fazer. Se você quiser usar variáveis ou funções (semi-) privadas em seu objeto, uma função construtora é a maneira de fazê-lo. Se o seu objeto contém apenas propriedades e métodos, um literal de objeto é adequado.
function SomeConstructor(){
var x = 5;
this.multiply5 = function(i){
return x*i;
}
}
var myObj = new SomeConstructor;
var SomeLiteral = {
multiply5: function(i){ return i*5; }
}
Agora o método multiply5entra myObje SomeLiteralfaz exatamente a mesma coisa. A única diferença é que myObj usa uma variável privada. O último pode ser útil em alguns casos. Na maioria das vezes, um literal de objeto é suficiente e uma maneira limpa e agradável de criar um objeto JS.
Você quer uma instância única do objeto para a página - Literal.
Você quer apenas transferir dados como objetos DTO simples GET SET: - Literal
Você deseja criar objetos reais com comportamentos de método, múltiplas instâncias - Função de construtor, Siga os princípios OOP, herança: - Funções de construtor.
Abaixo está o vídeo do youtube que explica em detalhes o que é literal, o que são funções construtoras e como elas diferem umas das outras.
Vá com o literal de objeto, é mais consistente e se expande melhor com a introdução de valores iniciais.
Conforme mencionado em https://www.w3schools.com/js/js_object_definition.asp
Usando um literal de objeto, você define e cria , um objeto em uma instrução.
Além disso
O literal de objeto cria apenas um único objeto. Às vezes, gostamos de ter um tipo de objeto que pode ser usado para criar muitos objetos de um tipo.
A função construtora Object () é um pouco mais lenta e detalhada. Como tal, a maneira recomendada de criar novos objetos em JavaScript é usar notação literal
Na verdade, acho que podemos ter métodos privados em literais de objeto. Considere o código abaixo:
var myObject = {
publicMethod: function () {
privateMethod1();
privateMethod2();
function privateMethod1(){
console.log('i am privateMethod1');
}
function privateMethod2(){
console.log('i am privateMethod2');
}
}
}
É questão de gosto, mas prefiro usar literais de objeto onde for possível.
// Object Literal e 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