javascript - Diferencia entre reopen() y reopenClass() en Ember.js
(2)
Después de experimentar con reopen () y reopenClass (), descubrí la diferencia entre ellos.
Aquí está el resultado de mi experimento.
var Person = Ember.Object.extend({
name:"",
alive:true,
sayHi:function(){
alert("hi");
}
});
Person.reopenClass({
age:30,
sayHo:function(){
alert("ho");
}
});
Person.reopen({
height:180,
sayYo:function(){
alert("yo");
}
})
var person = Person.create({
name:"Tom"
});
//person.reopenClass();//error!!
person.reopen({
sayWhat:function(){
alert("what!?");
},
weight:100
});
console.log(Person.alive);//undefined
console.log(Person.age);//30
console.log(Person.height);//undefined
console.log(Person.weight);//undefined
console.log(person.alive);//true
console.log(person.name);//Tom
console.log(person.height);//180
console.log(person.weight);//100
person.sayHi();//it works
//person.sayHo();//it doesn''t work
Person.sayHo();//it works
person.sayYo();//it works
//Person.sayYo();//it doesn''t work
//Person.sayWhat();//it doesn''t work
person.sayWhat();
Me confundí mientras estaba leyendo la documentación en emberjs.com http://emberjs.com/documentation/#toc_reopening-classes-and-instances
En la página de arriba, lo explica así.
Person.reopen({
// override `say` to add an ! at the end
say: function(thing) {
this._super(thing + "!");
}
});
Como puede ver, reabrir se usa para agregar propiedades y métodos a una instancia. Pero cuando necesite crear un método de clase o agregar las propiedades a la clase en sí, puede usar reopenClass.
Person.reopenClass({
createMan: function() {
return Person.create({isMan: true})
}
});
Person.createMan().get(''isMan'') // true
aunque la explicación dice "volver a abrir se usa para agregar propiedades y métodos a una instancia", creo que los dos ejemplos que se muestran arriba están hablando sobre cómo crear un método de clase o agregar las propiedades a la clase en sí, no a la instancia.
¿Estoy entendiendo mal lo que dice? No soy un programador experimentado, por lo que podría ser malentendido ...
por favor explique cuándo usar reabrir y volver a abrir Clase si no me entienden bien.
¡Gracias por adelantado!
La documentación no explica esto muy bien, pero es un tema muy complicado.
Por cierto, ahora vive en: http://emberjs.com/guides/object-model/reopening-classes-and-instances/
Uno de los problemas al hablar de Programación Orientada a Objetos es que a menudo se explica así: - Los Objetos son Objetos. Los objetos son instancias de una clase. - Las clases son objetos. - Las instancias son objetos y tienen una clase.
Esta explicación no ayuda a nadie en absoluto, y parece ser un problema recursivo (es decir, no hay fin para las referencias ... Un objeto es una instancia de una clase que es un objeto ... (repetir)).
Prefiero razonar de la siguiente manera:
Cuando las personas escriben código, a menudo describen clases e instancias. Las clases son un tipo de cosa. La fruta es un ejemplo de una clase. No estamos hablando de una cosa particular aquí, estamos hablando de toda una "clase" de cosas (de ahí el nombre).
Tenga en cuenta que no es una clase real. Solo es real cuando está "en vivo" y "en la memoria en la computadora". Hasta entonces, es una descripción de una clase. Por lo general, cuando las personas escriben código, escriben texto en un archivo de texto, y eso es solo una descripción del código real dentro de la computadora que ocurre cuando la computadora lo interpreta o lo compila en código de máquina.
El truco viene cuando te das cuenta de que una clase es en sí misma una descripción también. Es una descripción de toda una gama de objetos potencialmente reales.
En la computadora, cuando creas "una manzana", eso es una instancia. También es un objeto. Su clase es Apple, que en una computadora también es un objeto real. Cuando hablamos de Apple, esa es una idea. No existe en realidad, pero para que una computadora use algo debe hacerlo existir en su realidad, por lo que "Apple" es un objeto concreto, real, aunque también es una abstracción.
Creo que el último punto es lo que hace confundir a las personas sobre los objetos. Las clases son abstracciones, pero para que la computadora pueda hablar y razonar sobre ellas, tienen que hacerse realidad. Entonces, decidimos ... "clase significa abstracto, instancia significa real" ...
El problema es que tenemos herencia ... que trae la idea de capas de abstracción ... así que en nuestro modelo de fruta, tienes la manzana particular frente a ti, que también es una fruta, y la fruta también es un alimento . En realidad, Food no existe en realidad como una cosa o conjunto de cosas, a menos que digamos "este alimento, esta manzana", o "toda la comida en el mundo", o "la lasaña de tu mamá", entonces es una idea abstracta ...
Entonces, en nuestra computadora orientada a objetos, decimos "definir Comida que es un tipo de Objeto, ahora define la Fruta que es un tipo de Comida, ahora define a la Manzana que es una especie de Fruta, ahora define esta manzana, que es una especie de Manzana".
Ahora eso significa: - El objeto es la clase de Alimentos, y la Comida es una instancia de Objeto, ¡y la Comida también es una clase en sí misma! - ¡La comida es la clase de Fruit, y Fruit es una instancia de Food, y Fruit es también una clase! - Fruit es la clase de Apple, y Apple es una instancia de Fruit, ¡y Apple también es una clase! - Apple es la clase de tu manzana, y tu manzana es una instancia de Apple (y por lo tanto también de Fruit, Food and Object!). Sin embargo, NO es una clase, es solo un objeto.
Para razonar acerca de su manzana, diríamos que es un objeto (observe la letra minúscula o), también es una manzana, y una fruta y una comida, y ... aquí está el truco ... también es un objeto.
Así que ahora estamos en una posición en la que podemos entender que su manzana es un objeto, una instancia (de Apple, fruta, comida y objetos), una manzana, una fruta, un alimento y un objeto, pero no es una clase .
Entonces ... si agrega un método de instancia a una clase, entonces no estará disponible en la clase, pero estará disponible en todas las instancias de esa clase. Si agrega un método de clase, estará disponible en esa clase (y subclases). Entonces, si agrega un método de instancia a Apple, todas las instancias de Apple podrán ejecutar ese método. Sin embargo, si agrega un método solo a su manzana, solo su manzana tendrá ese método. Mi manzana no lo hará. Si agrega un método de clase a Apple, solo la clase Apple podrá ejecutar ese método (que, de manera conveniente, también puede acceder a través de todas sus instancias). Los métodos de clase son para cosas que no cambian instancias PARTICULARES . Los métodos de instancia son para cosas que SI cambian instancias PARTICULARES (generalmente). Lo mismo ocurre con las propiedades / atributos. No crearía un método de clase en la clase de Apple llamado "Color de Apple" porque parece que se relaciona con manzanas en particular (es decir, instancias). Espero que eso aclare un poco las cosas :)