1. Objeto Prototipo
1.1 Contras de constructores
JavaScript genera nuevos objetos a través de constructores, por lo que los constructores pueden considerarse como plantillas para objetos. Las propiedades y métodos del objeto de instancia se pueden definir dentro del constructor.
function cat (nombre, color) {this.name = name; this.color = color;} var cat1 = nuevo gato ('cabello grande', 'blanco'); cat1.name // 'Big Hair'cat1.color //' White 'La función CAT en el código anterior es un constructor. El atributo de nombre y el atributo de color se definen internamente. Todos los objetos de instancia generarán estos dos atributos. Sin embargo, hacerlo es un desperdicio de recursos del sistema, porque las propiedades no se pueden compartir entre instancias de objetos del mismo constructor.
function cat (nombre, color) {this.name = name; this.color = color; this.meow = function () {console.log ('mew, mew, mew ...'); };} var cat1 = new Cat ('Big Hair', 'White'); var cat2 = new Cat ('ei mao', 'negro'); cat1.meow === cat2.meow // falsoEn el código anterior, Cat1 y Cat2 son instancias del mismo constructor. Sin embargo, sus métodos mignificadores son diferentes, es decir, cada vez que se crea una nueva instancia, se creará un nuevo método mignificador. Esto no es necesario ni recursos del sistema WASTES, porque todos los métodos de meow son el mismo comportamiento y deben compartirse por completo.
1.2 El papel del atributo prototipo
En el lenguaje JavaScript, cada objeto tiene un objeto prototipo correspondiente, llamado objeto prototipo. Todas las propiedades y métodos definidos en el objeto prototipo pueden ser heredados por el objeto derivado. Este es el diseño básico del mecanismo de herencia JavaScript.
Además de este enfoque, JavaScript también proporciona otra forma de definir objetos de instancia. Sabemos que un constructor es una función, un objeto y también tiene sus propias propiedades y métodos. Un atributo prototipo apunta a otro objeto, que generalmente se llama objeto prototipo. Este objeto es muy especial. Siempre que las propiedades y los métodos definidos en IT puedan compartir por todos los objetos de instancia. Es decir, cuando el constructor genera un objeto de instancia, un atributo prototipo se asigna automáticamente al objeto de instancia.
función animal (name) {this.name = name;} animal.prototype.color = "white"; var cat1 = new animal ('Big Hair'); var cat2 = new Animal ('erimao'); cat1.color // 'white'cat2.color //' blanco 'El código anterior agrega un atributo de color al objeto prototipo del animal constructor. Como resultado, ambos objetos de instancia Cat1 y Cat2 llevan esta propiedad.
Más particularmente, siempre que se modifique el objeto prototipo, los cambios se reflejarán inmediatamente en el objeto de instancia.
Animal.prototype.color = "Yellow"; Cat1.Color // 'Yellow'cat2.Color //' Yellow '
El código anterior cambia el valor del atributo de color del objeto prototipo a amarillo, y el valor del atributo de color de los dos objetos de instancia cambiará inmediatamente. Esto se debe a que el objeto de instancia en realidad no tiene atributo de color, y todos leen el atributo de color del objeto prototipo. Es decir, cuando el objeto de instancia en sí no tiene una determinada propiedad o método, irá al objeto prototipo del constructor para encontrar la propiedad o el método. Esto es lo especial de los objetos prototipo.
Si el objeto de instancia en sí tiene una determinada propiedad o método, ya no buscará esta propiedad o método en el objeto prototipo.
Cat1.color = 'Black'; Cat2.Color // 'Yellow'animal.prototype.color // "Yellow";
El código anterior cambia la propiedad de color del objeto de instancia Cat1 a negro, de modo que ya no necesita leer la propiedad de color del objeto prototipo, y el valor de este último aún es amarillo.
En resumen, la función del objeto prototipo es definir las propiedades y métodos compartidos por todos los objetos de instancia, por lo que también se llama prototipo del objeto de instancia, y el objeto de instancia puede considerarse derivado del objeto prototipo.
Animal.prototype.walk = function () {console.log (this.name + 'está caminando.');};El código anterior define un método de caminar en el objeto animal.protype, que se llamará en todos los objetos de instancia de animales.
1.3 cadena prototipo
Dado que todos los objetos en JavaScript tienen constructores, y todos los constructores tienen atributos prototipo (en realidad todas las funciones tienen atributos prototipo), todos los objetos tienen sus propios objetos prototipo prototipo.
Por lo tanto, las propiedades y métodos de un objeto pueden definirse en sí mismo o en su objeto prototipo (como el método WALK en el código anterior). Dado que el prototipo en sí es un objeto y tiene su propio prototipo, se forma una cadena de prototipo. Por ejemplo, el objeto A es el prototipo del objeto B, el objeto B es el prototipo del objeto C, y así sucesivamente. Debido a que rastreando la raíz de la fuente, los objetos en la fuente se generan a partir del constructor de objeto (usando el comando nuevo objeto ()), por lo que si la traza la capa por capa, el prototipo de todos los objetos eventualmente se rastrea hasta el objeto.prototipo. Entonces, ¿hay un prototipo para Object.prototype? La respuesta puede ser sí o no, porque el prototipo de object.prototype es un nulo sin ninguna propiedad y método.
Object.getPrototypeOf (objeto.prototype) // nulo
El código anterior indica que el prototipo del objeto Object.prototype es nulo. Como NULL no tiene propiedades, la cadena prototipo termina aquí.
La función de la "cadena prototipo" es que al leer un cierto atributo de un objeto, el motor JavaScript primero busca los atributos del objeto en sí. Si no se puede encontrar, buscará su prototipo. Si aún no se puede encontrar, buscará el prototipo del prototipo. Y así sucesivamente, si el objeto.prototype en el nivel superior todavía no se encuentra, devuelve indefinido.
Por ejemplo, si el atributo prototipo de una función apunta a una matriz, significa que la función puede usarse como un constructor de matriz, porque los objetos de instancia que genera pueden llamar al método de matriz a través del atributo prototipo.
function myArray () {} myArray.prototype = new Array (); myArray.prototype.Constructor = myArray; var mine = new MyArray (); Mine.push (1, 2, 3); Mine.length // 3Mine Instance de Array // True (True (1,La mina en el código anterior es un objeto de instancia de MyArray. Dado que la propiedad prototipo de myArray apunta a una matriz, el mío puede llamar métodos de matriz (estos métodos realmente se definen en el objeto prototipo de la matriz). En cuanto a la última línea de instancia de expresión, sabemos que la instancia del operador se usa para comparar si un objeto es una instancia de un constructor, y la última línea indica que la mía es una instancia de matriz.
La instancia de la mina de Array // es equivalente a (Array === MyArray.Prototype.Constructor) || (Array === Array.Prototype.Constructor) || (Array === Object.Prototype.Constructor)
El código anterior ilustra la esencia de la instancia del operador, que se compara con los atributos del constructor de todos los objetos prototipo del objeto de instancia (para la introducción de este atributo, consulte la siguiente sección). Mientras haya uno, devolverá verdadero, de lo contrario devolverá falso.
1.4 Atributo de constructor
El objeto prototipo tiene un atributo de constructor que apunta a la función del constructor donde el objeto prototipo se encuentra de forma predeterminada.
función p () {} p.prototype.constructor === P // VerdaderoDado que el atributo del constructor se define en el objeto prototipo, significa que puede ser heredado por todos los objetos de instancia.
función p () {} var p = new P (); P.Constructor // Función P () {} P.Constructor === P.Prototype.Constructor // TrueP.HASOWNPROPERTY ('Constructor') // FalseEl código anterior indica que P es un objeto de instancia del constructor P, pero P en sí no tiene un atributo de constructor, que en realidad está leyendo el atributo P.Prototype.constructor en la cadena prototipo.
La función del atributo del constructor es distinguir en qué constructor se define el objeto prototipo.
function f () {}; var f = new f (); f.Constructor === F // truef.Constructor === Regexp // FalseEl código anterior significa que, utilizando la propiedad del constructor, se determina que la función de constructor de la variable F es F, no regexp.
2.Object.getPrototypeOf Método
El método Object.getPrototypeOf devuelve el prototipo de un objeto.
// El prototipo del objeto vacío es objeto.prototypeObject.getPrototypeOf ({}) === objeto.prototype // true // El prototipo de la función es function.prototypeFunction f () {} objeto.getPrototypeOf (f) === Function.prototype // verdad // Assume es un constructor y f es un objeto f es un objeto de f/ El prototipo de f es f.prototypevar f = new f (); object.getPrototypeOf (f) === f.prototype // true3.Object.Create Método
El método Object.Create se usa para generar un nuevo objeto y puede reemplazar el nuevo comando. Acepta un objeto como argumento y devuelve un nuevo objeto, que hereda completamente las propiedades del primero, es decir, el primero se convierte en el prototipo de la segunda.
var o1 = {p: 1}; var o2 = object.create (o1); o2.p // 1En el código anterior, el método Object.Create genera O2 basado en O1. En este momento, O1 se convierte en el prototipo de O2, es decir, O2 hereda todas las propiedades de O1.
El método Object.Create es básicamente equivalente al siguiente código. Si el navegador antiguo no admite el método Object.Create, puede usar el siguiente código para implementarlo usted mismo.
if (typeof object.create! == "function") {object.create = function (o) {function f () {} f.prototype = o; devolver nuevo f (); };}El código anterior muestra que el método Object.Create está creando esencialmente un nuevo constructor F, luego permite que el atributo prototipo de F apunte al objeto O como el prototipo, y finalmente devuelve una instancia de F, para que la instancia pueda heredar los atributos de o.
Los nuevos objetos generados en las siguientes tres maneras son equivalentes.
var o1 = object.create ({}); var o2 = object.create (object.prototype); var o3 = new Object ();Si desea generar un objeto que no herede ninguna propiedad (como tostring y valor de métodos), puede configurar el parámetro objeto. Cree en nulo.
var o = object.create (null); o.valueOf () // typeError: objeto [objeto objeto] no tiene método 'valorf'
El código anterior indica que si el prototipo de objeto O es nulo, no tiene algunas propiedades definidas en el objeto de objeto.
Al usar el método Object.Create, se debe proporcionar un prototipo de objeto, de lo contrario se informará un error.
Object.create () // typeError: el prototipo de objeto solo puede ser un objeto o nulo
El nuevo objeto generado por el método objeto. Crear dinámicamente hereda el prototipo. Agregar o modificar cualquier método en el prototipo se reflejará inmediatamente en el nuevo objeto.
var o1 = {p: 1}; var o2 = object.create (o1); o1.p = 2; o2.p // 2El código anterior indica que modificar el prototipo de objeto afectará el objeto recién generado.
Además del prototipo de objeto, el método Object.Create también puede aceptar un segundo parámetro, que representa el objeto de atributos que describe los atributos, que es el mismo formato que el método Object.defineProperties utilizado. Las propiedades del objeto que describe se agregarán al nuevo objeto.
var o = object.create (object.prototype, {p1: {valor: 123, enumerable: true}, p2: {valor: "ABC", enumerable: true}}); O.P1 // 123o.p2 // "ABC"Dado que el método Object.Create no usa un constructor, el operador de instancia de la instancia no se puede usar para determinar qué instancia del constructor es el objeto. En este momento, puede usar el siguiente método ISPrototypeOF para interpretar qué objeto es el prototipo.
4.SprototypeOf Método
El método ISPrototypeOF se usa para determinar si un objeto es un prototipo de otro objeto.
var o1 = {}; var o2 = object.create (o1); var o3 = object.create (o2); o2.IsprototypeOf (o3) // trueO1.IsprototypeOf (o3) // trueEl código anterior muestra que ISProtypeOF devuelve verdadero siempre que un objeto esté en la cadena prototipo.
5. Un ejemplo simple
var classDemo = function () {// Variable privada estática var private_static_var = 'aaaa'; // Método privado estático var private_static_func = function (key) {return Key + private_static_var; } // Método privado, la clave es pasar este var private_func = function (self, key) {return private_static_func (key + self.id); } var _class = function (id) {// constructor this.id = id; // Public Variable} // public Method_class.prototype.public_func = function (key) {return private_func (this, key); } return _class;} (); var a = new ClassDemo ('Hello World'); Alert (A.Public_Func ('World Hello'));No hay una manera simple de implementar variables privadas y variables/métodos estáticos públicos, pero la encapsulación es suficiente para hacerse hasta este punto.