2012-06-15 19 views
7

Estaba leyendo sobre cómo 'Crear una biblioteca JavaScript' antes y encontré estos códigos que me hacen querer arrancarme el pelo.¿Cómo funcionan estos fragmentos de código exactamente?

Aquí está el código que tiene mi cerebro en nudos:

if (window === this) { 
    return new _(id); 
} 

_ (id) es sólo el nombre de la función en la que se contiene el código. Aquí está el resto del código si necesita revisarlo usted mismo.

function _(id) { 

// About object is returned if there is no 'id' parameter 
var about = { 
    Version: 0.5, 
    Author: "Michael Jasper", 
    Created: "Fall 2010", 
    Updated: "23 November 2011" 
}; 

if (id) { 

    // Avoid clobbering the window scope: 
    // return a new _ object if we're in the wrong scope 
    if (window === this) { 
     return new _(id); 
    } 

    // We're in the correct object scope: 
    // Init our element object and return the object 
    this.e = document.getElementById(id); 
    return this; 
    } else { 
    // No 'id' parameter was given, return the 'about' object 
    return about; 
    } 
}; 

Nunca he visto 'devolver nueva función', pero me gustaría saber cómo funciona.

La otra pieza de código:

_.prototype = { 
    hide: function() { 
      this.e.style.display = 'none'; 
      return this; 
    } 

    show: function() { 
      this.e.style.display = 'inherit'; 
      return this; 
    } 
}; 

sé que este código añade nuevos métodos para el objeto, sino _ ¿Por qué se 'Retorno Este'? Intenté sin eso y funcionó bien.

Una última cosa, el enlace al artículo es http://www.mikedoesweb.com/2012/creating-your-own-javascript-library/

+0

Volver esto? Entonces, ¿puedes agregar algo más después? Adivinando – Anonymous

+6

El 'return this' habilita el encadenamiento, como en' magic(). Do(). Stuff() '. –

+0

sí, el encadenamiento es lo que quería decir ,, es como jQuery, pero jQuery es un poco más complejo y devuelve muchos objetos – Anonymous

Respuesta

16

El primer bit de código es esencialmente tratando de detectar cómo la función de "constructor" ha sido llamado ...

en javascript, puede utilizar una función para crear un objeto de dos maneras:

function _(id) { 
    this.someProperty = "stuff"; 
    //Do more stuff to "this" 
    return this; 
} 

//in this scenario, the "this" object will be the window object 
var myObject = _(id); 
console.log(window.someProperty); //outputs "stuff"; 
console.log(myObject.someProperty); //outputs "stuff"; 

//in this scenario, the "this" object is what get's actually returned... 
var myObject = new _(id); 
console.log(window.someProperty); //outputs "undefined" 
console.log(myObject.someProperty); //outputs "stuff" 

, por lo tanto, la comprobación de

if (window === this) { 
    return new _(id); 
} 

simplemente está ahí para asegurarse de que no llama accidentalmente al constructor sin la palabra clave new. esto sería malo, ya que cualquier propiedad que asignaría al objeto, se asignaría inmediatamente al espacio de nombre window ... lo que sería malo.


En cuanto a su segunda pregunta, el autor utiliza una return this; al final de cada método como fluent interface design pattern

esto permite la manipulación de objetos conveniente y de aspecto agradable. un ejemplo común de esto es jQuery, donde se puede métodos cadena en un solo objeto ...

$(".some-css-selector").click(function() { 
    ... do something to the selected objects during the "click" event 
}).keyup(function() { 
    ... do something to the same objects during the "keyup" event 
}); 

EDIT: un poco de más información adicional en respuesta a los comentarios de W3Geek siguientes:

de Douglas El libro de Crockford "Javascript: The Good Parts" (es una buena lectura si ingresas a JS ... solo tienen 70 páginas pero vale la pena leer cada una de ellas). operador


de Javascript new crea un nuevo objeto que hereda de miembro prototipo del operando, y luego llama el operando, la unión del nuevo objeto a this.Esto le da al operando (que mejor sería una función de constructor) una oportunidad de personalizar el nuevo objeto antes de que se devuelva al solicitante.

Si olvidó usar el `nuevo operador, que en lugar de obtener una llamada de función ordinaria, y esto está ligado al objeto global en lugar de a un nuevo objeto. Eso significa que su función será derribar variables globales cuando intenta inicializar los nuevos miembros. Eso es algo muy malo.

...

constructores son funciones que están diseñados para ser utilizados con el new prefijo. El prefijo new crea un nuevo objeto basado en el prototipo de la función y lo vincula con las funciones implícitas en el parámetro this. Si usted se olvida de utilizar el prefijo new, no se hará ningún nuevo objeto, y this se enlaza con el objeto global. Este es un error serio.


+0

Así que, básicamente, 'esto' contaminaría el alcance global si lo usáramos incorrectamente y ese 'control' se coloca allí para evitar que eso ocurra, ¿correcto? Mi pregunta es, ¿qué hay de malo con el espacio de nombres de la ventana? Veo mucho acerca de cómo es esto malo, pero nunca por qué. – W3Geek

+0

correcto. agregar propiedades al objeto "ventana" es malo porque hay muchos otros marcos que tienen acceso a él (y USARLO) también ... por ejemplo, las personas modifican el objeto 'window.location.href' (la URL actual) de tu navegador) todo el tiempo para "navegar" a una nueva página ... si de repente agregaste una propiedad de ubicación a tu objeto '_', destruiría por completo la propiedad window.location ... generalmente deberías sólo hay que poner las cosas que se están controlando en su propio espacio de nombres para asegurarse de que no tiene ningún efecto secundario –

+2

Nota: parece que hay algunas respuestas decentes aquí [en la "pérdida" de variables en el espacio de nombres global] (http://stackoverflow.com/questions/5951228/what-is-meant-by-leaking-into-global-scope). En general hay mucho debate que no sería adecuado para un comentario :) –

6

return this le da la capacidad de llamadas a métodos cadena. Puede hacer cosas realmente interesantes y útiles, como _.show().hide(). :)

Cuestiones relacionadas