2011-08-09 9 views
8

La respuesta a esta pregunta: ¿ What is the initial value of a JavaScript function's prototype property?¿Qué significa 'es una instancia de' en Javascript?

tiene esta frase:

El valor inicial del prototipo en cualquier instancia de función recién creada es una nueva instancia de objeto

Por lo como sé, Javascript no tiene clases y la palabra 'instancia' no tiene sentido en mi cabeza. ¿Cómo debería uno interpretar 'instancia' en Javascript?

Lo siento, no tengo suficientes representantes para poner mi pregunta en el hilo de comentarios de esa respuesta.

Respuesta

16

Tiene razón de que JavaScript no tiene clases (todavía), pero sí tiene funciones de constructor, un operador instanceof que define una relación entre objetos y constructores, y una forma de herencia basada en cadenas de prototipos.

obj instanceof ctor es verdadero cuando ctor.prototype está en la cadena de prototipos de obj.

Modulo por debajo de la advertencia, se podría implementar en instanceof EcmaScript 5 por lo tanto

function isInstanceOf(obj, ctor) { 
    var proto = ctor.prototype; 
    if (typeof obj === "object" || typeof obj === "function") { 
    while (obj) { 
     if (obj === proto) { return true; } 
     obj = Object.getPrototypeOf(obj); 
    } 
    } 
    return false; 
} 

a menos que vaya alrededor de la reasignación de prototipos (o = new MyConstructor(); MyConstructor.prototype = somethingElse) debería ser el caso que new MyConstructor() instanceof MyConstructor.

La sección 15.3.5.3 explica esto en detalle.

15.3.5.3 [[HasInstance]] (V)

Supongamos F es un objeto Function.

Cuando el método interno [[HasInstance]] de F se llama con el valor V, se toman los pasos siguientes:

  1. Si V no es un objeto, volver falsa.
  2. Sea O el resultado de llamar al método interno [[Get]] de F con el nombre de propiedad "prototipo".
  3. Si el tipo (O) no es Object, ejecute una excepción TypeError.
  4. Repita

    1. Sea V el valor de la [[Prototype]] propiedad interna de V.
    2. Si V es nulo, de regreso falsa.
    3. Si O y V se refieren al mismo objeto, devuelve verdadero.

Esto no es toda la historia porque los objetos del host (como nodos DOM) se les permite poner en práctica el método interno [[HasInstance]] a su gusto, pero la mayoría de los navegadores implementan objetos host a comportarse tan de cerca a los objetos nativos como sea posible.

+0

No dice '(yet)' :(las clases todavía son de tipo strawman. Si tenemos suerte no entrarán en ES6! – Raynos

-2

Javascript está orientado a objetos, por lo que tiene clases. Simplemente no hay una directiva explícita de "clase", como la que tendría en otros lenguajes de OOP.

+4

Javascript no tiene clases, es ap lenguaje basado en rototipo que es una forma diferente de implementar OOP. Las diferencias pueden ser sutiles, pero son importantes. –

5

JavaScript no tiene clases, pero tiene Tipos. Puede definir su propio tipo y crear una nueva instancia utilizando el new palabra clave:

function Foo(initialValue) { 
    this.value = initialValue || 0; 
} 
var foo = new Foo(17); 
var fooIsAFoo = foo instanceof Foo; // true! 
var fooIsAnObject = foo instanceof Object; // also true! We have inheritance here :) 
+0

¿Puede respaldar el concepto de "Tipos" con referencias a la especificación? Tengo la sensación de que solo hay tipos nativos y 'Foo' no es un tipo. – Raynos

1

Javascript no utilizar la herencia clásica, que utiliza prototypal inheritance donde todo es un "objeto" y la herencia se logra mediante la clonación, por ejemplo, :

var myPrototype = function() { 
    var privateMember = "I am private"; 
    var publicMember = "I am public"; 
    var publicMethod = function() { 
     alert(privateMember); 
    } 
    return { 
     publicMember = publicMember, 
     publicMethod = publicMethod 
    } 
} 

var myInstace = new myPrototype(); 
myInstance.publicMethod(); 

aquí myInstance puede decirse que es una "instancia de" myPrototype, pero en realidad lo que sucedió es mediante el uso de la palabra clave new ha clonado myPrototype para crear myInstance.

3

En JS, una función es un Objeto. Lleva un tiempo acostumbrarse a eso, pero es verdad. Tira eso un poco y el código que ves que otros usan tendrá más sentido. Si ha visto Javascript donde las personas pasan una función() {} como parámetro a otra función, eso es una prueba de que las funciones son objetos de primera clase.

Una vez que pueda entender esto (me tomó un tiempo), entonces necesita comprender que si realiza una función, puede obtener una nueva instancia de la misma. Consulte el siguiente código:

function FooName(){ 
    var name; 
    this.setName = function(n){ 
     this.name = n; 
    } 
    this.getName = function(){ 
     return this.name; 
    } 
} 
var n1 = new FooName(); 
var n2 = new FooName(); 
n1.setName("FOO"); 
n2.setName("BAR"); 

En este punto, tiene dos instancias del método FooName: n1 y n2. Es una especie de convención en JS nombrar su función de creación de instancias con una primera letra mayúscula, en lugar de la primera letra minúscula del cliente. En este ejemplo, indico que mi función se puede instanciar nombrando FooName en lugar de fooName. Espero que esto tenga sentido.

En el ejemplo anterior, n1 tiene tres propiedades. Una propiedad de nombre privado, una propiedad setName pública y una propiedad pública getName. Cada vez que crea una instancia de un nuevo FooName, se crearán una copia de getName y setName. Eso puede desperdiciar espacio en la memoria. Como getName y setName no van a cambiar, no necesito una nueva copia para cada instancia de FooName. Aquí es donde entran los prototipos.

Puede decir lo siguiente, y luego getName y setName solo existirán una vez en la memoria, lo que liberará la memoria, lo que es bueno.

FooName.prototype.setName = function(n){ 
    this.name = n; 
} 
FooName.prototype.getName = function(){ 
    return this.name; 
} 

Si se quita la getNombre y setName de la función FooName, entonces ahora usted tendrá una FooName "clase" que tiene dos métodos, getNombre y setName.

Juega con ella.Déjeme saber si usted tiene preguntas.

+0

No estoy seguro de si esto responde a la pregunta de @loldrup pero seguro me dio alguna idea. Gracias +1 – brenjt

+0

Verdadero ... Supongo que diría que "instanciaof" significa que tiene una función y ha declarado una nueva. La palabra clave "nuevo" es lo que te dará la instancia. Ejemplo, mi código anterior, var n3 = FooName no es lo mismo que var n3 = new FooName. La diferencia al dejar la nueva salida es MUY SIGNIFICATIVA. Si dejó el "nuevo", todos los usos de la palabra "esto" se referirían a la ventana misma. El "esto" en JS se refiere al contexto en el que se llama. Si lo llamas dentro de una instancia obj, se refiere al obj. Si lo llamas fuera de una instancia obj, es global. – frosty

+1

"Si elimina getName y setName de la función FooName, entonces ahora tendrá una" clase "FooName que tiene dos métodos, getName y setName." Es decir, el objeto prototipo del objeto (función -) FooName ahora tiene estas funciones y, debido al método de resolución de nombres que puede seguir a prototype-chains, todas las instancias de FooName podrán encontrar estos métodos . ¿Es eso lo que querías decir? – loldrup

Cuestiones relacionadas