Buscar..


Prototipo de función estándar

Comience por definir una función Foo que usaremos como constructor.

function Foo (){}

Al editar Foo.prototype , podemos definir propiedades y métodos que serán compartidos por todas las instancias de Foo .

Foo.prototype.bar = function() {
  return 'I am bar';
};

Luego podemos crear una instancia usando la new palabra clave y llamar al método.

var foo = new Foo();

console.log(foo.bar()); // logs `I am bar`

Diferencia entre Object.key y Object.prototype.key

A diferencia de lenguajes como Python, las propiedades estáticas de la función constructora no se heredan a las instancias. Las instancias solo se heredan de su prototipo, que se hereda del prototipo del tipo principal. Las propiedades estáticas nunca se heredan.

function Foo() {};
Foo.style = 'bold';

var foo = new Foo();

console.log(Foo.style); // 'bold'
console.log(foo.style); // undefined

Foo.prototype.style = 'italic';

console.log(Foo.style); // 'bold'
console.log(foo.style); // 'italic'

Nuevo objeto del prototipo.

En JavaScript, cualquier objeto puede ser el prototipo de otro. Cuando un objeto se crea como un prototipo de otro, heredará todas las propiedades de su padre.

var proto = { foo: "foo", bar: () => this.foo };

var obj = Object.create(proto);

console.log(obj.foo);
console.log(obj.bar());

Salida de consola:

> "foo"
> "foo"

NOTA Object.create está disponible en ECMAScript 5, pero aquí hay un polyfill si necesita soporte para ECMAScript 3

if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}

Fuente: http://javascript.crockford.com/prototypal.html


Object.create ()

El método Object.create () crea un nuevo objeto con el objeto prototipo y las propiedades especificados.

Sintaxis: Object.create(proto[, propertiesObject])

Parámetros :

  • proto (El objeto que debería ser el prototipo del objeto recién creado).
  • propertiesObject (Opcional. Si se especifica y no está indefinido, un objeto cuyas enumerables propiedades propias (es decir, aquellas propiedades definidas en sí mismo y no enumerables propiedades a lo largo de su cadena de prototipos) especifica los descriptores de propiedades que se agregarán al objeto recién creado, con el correspondiente nombres de propiedades. Estas propiedades corresponden al segundo argumento de Object.defineProperties ().)

Valor de retorno

Un nuevo objeto con el objeto prototipo especificado y las propiedades.

Excepciones

Una excepción TypeError si el parámetro proto no es nulo o un objeto.

Herencia prototípica

Supongamos que tenemos un objeto plano llamado prototype :

var prototype = { foo: 'foo', bar: function () { return this.foo; } };

Ahora queremos otro objeto llamado obj que herede del prototype , que es lo mismo que decir que prototype es el prototipo de obj

var obj = Object.create(prototype);

Ahora todas las propiedades y métodos del prototype estarán disponibles para obj

console.log(obj.foo);
console.log(obj.bar());

Salida de consola

"foo"
"foo"

La herencia prototípica se realiza a través de referencias de objetos internamente y los objetos son completamente mutables. Esto significa que cualquier cambio que realice en un prototipo afectará inmediatamente a todos los demás objetos de los que el prototipo sea prototipo.

prototype.foo = "bar";
console.log(obj.foo);

Salida de consola

"bar"

Object.prototype es el prototipo de cada objeto, por lo que se recomienda encarecidamente que no te metas con él, especialmente si utilizas una biblioteca de terceros, pero podemos jugar con él un poco.

Object.prototype.breakingLibraries = 'foo';
console.log(obj.breakingLibraries);
console.log(prototype.breakingLibraries);

Salida de consola

"foo"
"foo"

Dato curioso , he usado la consola del navegador para hacer estos ejemplos y he roto esta página agregando la propiedad breakingLibraries .


Herencia pseudo-clásica

Es una emulación de la herencia clásica utilizando la herencia prototípica que muestra qué tan poderosos son los prototipos. Fue hecho para hacer que el lenguaje sea más atractivo para los programadores que vienen de otros idiomas.

6

NOTA IMPORTANTE : desde ES6 no tiene sentido usar herencia pseudocálica ya que el lenguaje simula clases convencionales . Si no estás usando ES6, deberías . Si aún desea utilizar el patrón de herencia clásico y está en un entorno ECMAScript 5 o inferior, entonces su mejor apuesta es pseudo-clásica.

Una "clase" es solo una función que está diseñada para ser llamada con el new operando y se usa como un constructor.

function Foo(id, name) {
    this.id = id;
    this.name = name;
}

var foo = new Foo(1, 'foo');
console.log(foo.id);

Salida de consola

1

foo es una instancia de Foo. La convención de codificación de JavaScript dice que si una función comienza con mayúsculas y minúsculas, se puede llamar como un constructor (con el new operando).


Para agregar propiedades o métodos a la "clase", debe agregarlos a su prototipo, que se puede encontrar en la propiedad prototype del constructor.

Foo.prototype.bar = 'bar';
console.log(foo.bar);

Salida de consola

bar

De hecho, lo que Foo está haciendo como "constructor" es simplemente crear objetos con Foo.prototype como su prototipo.


Puedes encontrar una referencia a su constructor en cada objeto.

console.log(foo.constructor);

función Foo (id, nombre) {...

console.log({ }.constructor);

Función Objeto () {[código nativo]}

Y también verifique si un objeto es una instancia de una clase dada con el operador instanceof

console.log(foo instanceof Foo);

cierto

console.log(foo instaceof Object);

cierto

Configurando el prototipo de un objeto

5

Con ES5 +, la función Object.create se puede usar para crear un objeto con cualquier otro objeto como prototipo.

const anyObj = {
    hello() {
        console.log(`this.foo is ${this.foo}`);
    },
};

let objWithProto = Object.create(anyObj);
objWithProto.foo = 'bar';

objWithProto.hello(); // "this.foo is bar"

Para crear explícitamente un Objeto sin un prototipo, use null como el prototipo. Esto significa que el Objeto tampoco se heredará del Object.prototype y es útil para los Objetos utilizados para los diccionarios de verificación de existencia, por ejemplo

let objInheritingObject = {};
let objInheritingNull = Object.create(null);

'toString' in objInheritingObject; // true
'toString' in objInheritingNull ; // false
6

Desde ES6, el prototipo de un objeto existente se puede cambiar utilizando Object.setPrototypeOf , por ejemplo

let obj = Object.create({foo: 'foo'});
obj = Object.setPrototypeOf(obj, {bar: 'bar'});

obj.foo; // undefined
obj.bar; // "bar"

Esto se puede hacer en casi cualquier lugar, incluso en this objeto o en un constructor.

Nota: este proceso es muy lento en los navegadores actuales y se debe usar con moderación; en su lugar, intente crear el Objeto con el prototipo deseado.

5

Antes de ES5, la única forma de crear un Objeto con un prototipo definido manualmente era construirlo con new , por ejemplo

var proto = {fizz: 'buzz'};

function ConstructMyObj() {}
ConstructMyObj.prototype = proto;

var objWithProto = new ConstructMyObj();
objWithProto.fizz; // "buzz"

Este comportamiento es lo suficientemente cercano a Object.create que es posible escribir un polyfill.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow