2011-02-01 9 views
78

Me estoy confundiendo sobre la forma en que debería crear un objeto en javascript. Parece que hay al menos dos formas. Una es usar notación literal de objetos mientras que la otra usa funciones de construcción. ¿Hay una ventaja de uno sobre el otro?¿Debo utilizar literales de objeto o funciones de constructor?

+1

La mejor respuesta: http://stackoverflow.com/questions/4597926/creating-objects-new-object-or-object-literal-notation - En resumen, puede configurar una función para crear instancias formar notación literal también. Al hacer esto, cada instancia contiene todos los métodos, mientras que con un constructor todas las instancias se refieren a los métodos prototipo.Es decir, el constructor tiene un mejor rendimiento de la memoria. – Federico

Respuesta

106

Si no tiene un comportamiento asociado con un objeto (es decir, si el objeto es solo un contenedor de datos/estado), usaría un objeto literal.

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

Aplicar KISS principle. Si no necesita nada más que un simple contenedor de datos, vaya con un simple literal.

Si desea agregar comportamiento a su objeto, puede ir con un constructor y agregar métodos al objeto durante la construcción o darle a su clase un prototipo.

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

una clase como esta también actúa como un esquema para el objeto de datos: Ahora tiene algún tipo de contrato (a través del constructor) qué propiedades inicializa/contiene el objeto. Un literal libre es solo una masa amorfa de datos.

Es lo mismo que tener una función externa verify que actúa sobre un viejo objeto de datos sin formato:

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

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

Sin embargo, esto no es favorable con respecto a la encapsulación: Lo ideal sería que todos los datos + comportamiento asociado con una la entidad debe vivir junta.

+7

Gran explicación, pero ¿qué hay de poner las funciones en un objeto literal? He visto esto hecho antes. En realidad, la siguiente publicación tiene un ejemplo de esto. – chobo

+20

Si incluye las definiciones de funciones como parte del objeto literal, o utiliza la función 'this.fn = ... 'enfoque en un constructor, cada una de sus instancias de objetos tendrá sus propias copias de funciones. Usando el enfoque de prototipo, adjuntará cada función una vez y solo una vez: serán heredadas por las instancias a través de la herencia de prototipos. –

+11

I cree que se olvidó de algo importante. Solo la función de constructor puede proporcionar tanto miembros privados como miembros públicos (encapsulación) en el literal del objeto, todos son públicos. –

0

Vaya con el objeto literal, es más consista y se expande mejor con la introducción de los valores iniciales.

+0

¿Cómo se crean variables privadas en un objeto literal? – EhevuTov

+0

No puede realmente, no es relevante para la pregunta original, así que solo le daré un enlace: http://javascript.crockford.com/private.html – Tom

+1

En realidad, es relevante porque hay una diferencia , hay una razón para usar uno u otro dependiendo de ciertas situaciones; en este caso, sería si quieres variables privadas o no. Puede crear variables privadas en un literal creando primero una función de cierre en su literal, pero es mucho más feo en mi opinión y difícil de leer. – EhevuTov

5

Depende de lo que quieras hacer. Si desea usar variables o funciones (semi) privadas en su objeto, una función constructora es la manera de hacerlo. Si su objeto solo contiene propiedades y métodos, un objeto literal está bien.

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

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

Ahora el método multiply5 en myObj y SomeLiteral hacen exactamente lo mismo. La única diferencia es que myObj usa una variable privada. Esto último puede ser útil en algunos casos. La mayoría de las veces, un Object literal es suficiente y una forma agradable y limpia de crear un objeto JS.

+0

¿Cuál es la diferencia entre una función y un método? Vengo de un fondo C# por lo que para mí una función es independiente y un método es solo una función que es parte de una clase. – chobo

+1

No hay mucha diferencia, consulte, por ejemplo, http://www.web-source.net/javascript_tutorial/javascript_functions_methods.htm. En realidad, en DOMscripting (js del lado del cliente en un navegador), todas las funciones se convierten en métodos del objeto ventana (el espacio de nombres global) diría (puede direccionar todas las funciones 'independientes' como ventana. [Somefunction]. – KooiInc

81

Básicamente se reduce a si necesita varias instancias de su objeto o no; objeto definido con un constructor le permite tener múltiples instancias de ese objeto. Los literales de objeto son básicamente singletons con variables/métodos que son 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 
+1

Este es un muy buen punto a tener en cuenta a la hora de decidir. Gracias. – zkent

+0

En mi experiencia, esto es exactamente lo que hace la diferencia. Gran ejemplo claro. – Air

+0

gr8 explicación ... información muy útil – Vikash

7

Otra forma de crear objetos de una manera uniforme es utilizar una función que devuelve un 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! 

Dado que las funciones en JavaScript son los cierres que podemos utilizar variables y métodos privados y evitar new.

De http://javascript.crockford.com/private.html en variables privadas en JavaScript.

5

El siguiente código muestra tres métodos para crear un objeto, la sintaxis de Object Literal, un constructor de funciones y Object.create().La sintaxis literal del objeto simplemente crea y objeta sobre la marcha y, como tal, su __prototype__ es el objeto Object y tendrá acceso a todas las propiedades y métodos de Object. Estrictamente, desde la perspectiva de un patrón de diseño, se debe usar un simple Object literal para almacenar una sola instancia de datos.

El constructor de funciones tiene una propiedad especial llamada .prototype. Esta propiedad se convertirá en __prototype__ de cualquier objeto creado por el constructor de función. Todas las propiedades y métodos añadidos a la propiedad .prototype de un constructor de funciones estarán disponibles para todos los objetos que cree. Se debe usar un constructor si necesita múltiples instancias de los datos o requiere un comportamiento de su objeto. Tenga en cuenta que el constructor de funciones también se usa mejor cuando quiere simular un patrón de desarrollo privado/público. Recuerde poner todos los métodos compartidos en el .prototype para que no se creen en cada instancia de objeto.

La creación de objetos con Object.create() utiliza un objeto literal como __prototype__ para los objetos creados con este método. Todas las propiedades y métodos agregados al objeto literal estarán disponibles para todos los objetos creados a partir de él a través de una verdadera herencia prototípica. Este es mi 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); 
+0

Desde que declaró la función dentro de un objeto literal. ¿Significa eso que cuando creas un objeto usando 'Object.create' la función dentro del literal será única por instancia? – JohnnyQ

-1

// objeto literal y constructor de objeto

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 
+1

¿Dónde en su ejemplo se declara el objeto literal? – JohnnyQ

2

enter image description here

¿Quieres sola instancia del objeto de la página - literal.

¿Quieres sólo la transferencia de datos como DTO objetos simples SET GET: - literal

¿Quieres crear objetos reales con los comportamientos de métodos, varias instancias - Función constructora, seguir los principios de POO, la herencia: - Las funciones constructoras .

A continuación se muestra el video de youtube que explica en detalle qué es literal, qué son las funciones de constructor y cómo se diferencian entre sí.

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

0

Como se mencionó en https://www.w3schools.com/js/js_object_definition.asp

Usando un objeto literal, tanto definir y crear, uno objeto en uno comunicado.

También

Objeto literal sólo para crear un único objeto. A veces nos gusta tener un tipo de objeto tipo que se puede utilizar para crear muchos objetos de un tipo.

Cuestiones relacionadas