Honestamente, yo no sabía cómo hacer el título más corto.

Aprendí a escribir un plugin de jQuery mediante el estudio de la fuente de SlidesJS plugin. Cuando me encontré con algo nuevo, yo sólo le pedí a mi buen amigo Google y la mayoría de las veces, obtuvo una respuesta satisfactoria. Honestamente, sin embargo, nunca he hecho un gran esfuerzo. Todo lo que sé es que $ es (probablemente) una abreviatura de jQuery constructor del objeto y que $() y jQuery() son la misma cosa siempre jQuery está incluido.

Recientemente, sin embargo, traté de entender la ciencia detrás de jQuery y cómo escribir una buena plugin de jQuery. Me encontré con una muy buena artículo en la que el autor se enumeran varios plantillas para la creación de un plugin de jQuery. Ya que el resto eran demasiado complejo de entender para mí, me gustó la primera: Un Ligero Inicio. Ahora, aquí está el código para la plantilla.

/*!
 * jQuery lightweight plugin boilerplate
 * Original author: @ajpiano
 * Further changes, comments: @addyosmani
 * Licensed under the MIT license
 */


//the semi-colon before the function invocation is a safety 
//net against concatenated scripts and/or other plugins 
//that are not closed properly.
;(function ( $, window, document, undefined ) {

    //undefined is used here as the undefined global 
    //variable in ECMAScript 3 and is mutable (i.e. it can 
    //be changed by someone else). undefined isn't really 
    //being passed in so we can ensure that its value is 
    //truly undefined. In ES5, undefined can no longer be 
    //modified.

    //window and document are passed through as local 
    //variables rather than as globals, because this (slightly) 
    //quickens the resolution process and can be more 
    //efficiently minified (especially when both are 
    //regularly referenced in your plugin).

    //Create the defaults once
    var pluginName = 'defaultPluginName',
        defaults = {
            propertyName: "value"
        };

    //The actual plugin constructor
    function Plugin( element, options ) {
        this.element = element;

        //jQuery has an extend method that merges the 
        //contents of two or more objects, storing the 
        //result in the first object. The first object 
        //is generally empty because we don't want to alter 
        //the default options for future instances of the plugin
        this.options = $.extend( {}, defaults, options) ;

        this._defaults = defaults;
        this._name = pluginName;

        this.init();
    }

    Plugin.prototype.init = function () {
        //Place initialization logic here
        //You already have access to the DOM element and
        //the options via the instance, e.g. this.element 
        //and this.options
    };

    //A really lightweight plugin wrapper around the constructor, 
    //preventing against multiple instantiations
    $.fn[pluginName] = function ( options ) {
        return this.each(function () {
            if (!$.data(this, 'plugin_' + pluginName)) {
                $.data(this, 'plugin_' + pluginName, 
                new Plugin( this, options ));
            }
        });
    }

})( jQuery, window, document );

He incluido los comentarios, así como para referirse a ellos en mis preguntas.

Tengo un crudo idea de por qué window y document se han incluido en el argumento de la función anónima que se envuelve el plugin (no sé qué otra cosa lo llaman), porque es dada en los comentarios que sorta a poco se acorta el tiempo de ejecución. Pero, ¿cómo funciona eso? Cualquier argumento de dicha función anónima envolver el plugin se pasa a donde? Y de qué manera son abordados en el plugin?

Normalmente, me gustaría hacer $(window).resize(function(){}) pero que no funciona en este caso. Si hago console.log(window) dentro del Plugin función, se dice que ‘no’.

Lo que me lleva a la otra pregunta que es: ¿cuál es indefinido? ¿No es un tipo de datos que está asignado a una objeto que no está definido en el ámbito de aplicación? ¿Cómo puede ser pasado como argumento? No los argumentos tienen que ser objetos? Hay un par de líneas escritas sobre esto en los comentarios, pero no entiendo una palabra de lo: <por lo que podemos asegurar que su valor está definida> whaaa?

Para resumir:

  • Lo que de hecho se entiende por function($)?
  • ¿Por qué debo incluir window, document y undefined como argumentos de function($)?
  • Si lo hago, ¿cómo puedo acceder a la real window y document objetos?
  • undefined qué, y por qué?

Por favor, ir fácil en mí. Nunca estudié lenguaje de programación como un tema para el propósito expreso de las aplicaciones de la escritura. Estudié C básicas para la escritura de hardware orientado a las rutinas de bajo nivel para el pequeño núcleo de los microcontroladores y eso es sólo acerca de él. Me hizo aprender C++ ampliamente y un poco de Java por mi cuenta. Solo así que vas a saber qué esperar.

4 Comentarios

  1. 23

    Al escribir una función como:

    (function (foo, bar) {
        return foo.getElementById(bar);
    })(document, "myElement")

    a continuación, la función se llama inmediatamente con argumentos document y "myElement" para los parámetros foo y bar. Por lo tanto, dentro de la función, foo.getElementById(bar) es equivalente a document.getElementById("myElement").

    Asimismo, en su plugin de ejemplo, que son inmediatamente llamar a la función con los argumentos jQuery, document, window.

    Lo que de hecho se entiende por function($)?

    La $ representa simplemente una referencia a un jQuery objeto que es pasado a la función de contenedor. Más tarde, cuando el anónimo se llama a la función con (jQuery, window, document), el $ de referencia dentro de la función hace referencia a la jQuery objeto. Esto se realiza para un número de razones, no menos importante de los cuales es que $ es más rápido para escribir. También permite al usuario aplicar el plugin en el contenedor a un instancia en particular de jQuery, producido tal vez por jQuery.noConflict().

    ¿Por qué debo incluir window, document y undefined como argumentos de function($)?

    No necesidad para incluir estos. El autor original de este razonamiento es que la asignación de la función de las variables locales para hacer referencia a estas acortará el tiempo necesario para resolver estas variables. Afirmo que el ahorro es insignificante; yo personalmente no lo molestan menos que utiliza mucho de referencias a window y/o document.

    Como para undefined, el original propósito del autor en la inclusión de esta es para asegurarse de que alguien no se ha alterado la undefined variable global en EcmaScript 4 (edit: en realidad ECMAScript 3 — versión 4 nunca lo hizo) o anterior. De nuevo, no puedo imaginar este problema apareciendo. Si usted está realmente preocupado de que esto podría ser un problema, sólo tienes que incluir algo como esto en su función:

    if(typeof undefined !== "undefined") {
        undefined = void 0;
    }

    Si lo hago, ¿cómo puedo acceder a la real window y document objetos?

    Todo lo que tiene que hacer es asegurarse de que la llamada a la función en el extremo de su función anónima que pasa en el real (jQuery, ventana de documento) de los parámetros. O, no incluya el window y document argumentos en la función de la firma. De cualquier manera, usted será referente a la real objetos, sin importar el nivel de direccionamiento indirecto.

    undefined qué, y por qué?

    undefined es una variable global de tipo «no definido». Los campos que no se han inicializado son exactamente iguales (===) a indefinido. Permite al programador para diferenciar entre deliberadamente un valor nulo y una simple sin inicializar uno. En ECMAScript 5 y más tarde, undefined es de sólo lectura. Antes de eso, es posible que otros código podría modificar el valor de undefined. Usted puede siempre obtener el verdadero valor undefined con la expresión void 0… como en myUndefinedVar = void 0;.

    • Te refieres a ECMAScript 3, ES4 en realidad fue abortado. Aparte de eso, bonita respuesta!
    • +1, por CIERTO, es imposible saber la diferencia entre una variable que no se ha asignado ningún valor y que se le ha asignado un valor de undefined.
    • eso no es cierto. Por ejemplo en un navegador puede comprobar ventana.hasOwnProperty(‘neverCreatedVariable’) devolverá false, pero la ventana.hasOwnProperty(‘assignedVariableToUndefined’) devolverá true. En una función usted puede hacer esto.hasOwnProperty
    • global en el contexto de ejecución es el único en el que usted puede usar hasOwnProperty para la prueba de una variable, no puede ser utilizado para la prueba de función del ámbito de variables (no es una solución general). El po y la respuesta está en función del contexto de ejecución.
    • si usted está en una función puede agregar el «use strict» y el uso de un bloque try para coger el ref de error. No es algo que uno hace, en general, pero el punto es que hay una diferencia entre las variables asignadas indefinido y que no están definidos y usted puede comprobar si los casos de uso y deseo de hacerlo.
    • Con mucho retraso, pero esto merece ser la respuesta que elijas. No es que cualquiera de los otros que fueron sub-par. Yo estaba pasando por mi historia cuando vio que yo no había seleccionado un «aceptado respuesta». Usted tendrá que perdone mis modales. Yo era un idiota en ese entonces (como es evidente a partir de mi pregunta). Estoy un poco menos de un idiota ahora, gracias a los héroes como tú. Saludos! 🙂

  2. 3

    Lo que se entiende por function($)?

    Pasando $ como argumento a la función hace posible para que usted utilice el jQuery de taquigrafía objeto, que, como usted claramente identificado, es simplemente un alias de la jQuery objeto (también echar un vistazo a jQuery.noConflict()).

    ¿Por qué debo incluir window, document y undefined como argumentos de function($)?
    Tengo un crudo idea de por qué la ventana de documento y se han incluido en el argumento de la función anónima que se envuelve el plugin (no sé qué otra cosa lo llaman), ya que se da en los comentarios que sorta a poco se acorta el tiempo de ejecución. Pero, ¿cómo funciona eso? Cualquier argumento de dicha función anónima envolver el plugin se pasa a donde?

    Pasando window y document como variables locales a poco se acorta el tiempo de ejecución porque es más fácil y más rápido para acceder a una variable local de una variable global, porque las variables locales son los primeros en la cadena de. Qué tipo de respuestas a la segunda cuestión: los argumentos se pasan dentro de la función anónima ámbito, que es el punto entero de hacer una función anónima de todos modos: para crear un cierre.

    Los argumentos que se pasan al final de la función, donde se ve el último paréntesis. La variable window en su cierre se refiere a la global window porque se la pasó al final.

    La razón por la que usted pase undefined es porque undefined es un Javascript lío. Básicamente, undefined es una propiedad de la objeto global, es decir, es una variable, un singleton. No está protegido, que significa que puede ser anulado. Esto significa que usted podría tener un undefined que en realidad es definido.

    Pasando undefined asegurarse de que, incluso si alguien metido con undefined en el ámbito global (nunca confíes en el ámbito global! :)), que aún así obtener una correcta undefined.

    También, las mismas razones de rendimiento se aplican a undefined.

    Si lo hago, ¿cómo puedo acceder a la ventana real y objetos de documento?

    Usted ya que el acceso a ellos, porque se pasa a la función. Y, como tales, son capaces de manipular.

  3. 2

    Antes de contestar en detalle permítanme señalar que a diferencia de otros lenguajes de programación, javascript es un poco extraño por dos razones: en primer lugar, fue creado a toda prisa, esto significaba un montón de cosas no obtener refinado o bien implementada. Segundo fue adoptado por internet muy, muy rápidamente y Microsoft copió el lenguaje de forma muy rápida y muy precisa (incluyendo los errores en el lenguaje). El resultado de esto es que, tratando de corregir los errores en el diseño del lenguaje fue duro y/o imposible, porque no quiero romper la compatibilidad con sitios web existentes.

    Ahora a entrar en los detalles:

    Lo que de hecho se entiende por función($)

    Nada especial. En función de javascript y los nombres de las variables se les permite el uso de las letras a-z incluyendo mayúsculas, los números 0-9 y los símbolos $ y _. No existen otras restricciones sobre cómo pueden ser utilizados. Aunque existen pautas y convenciones, algunos mencionados por el lenguaje de especificación en sí, algunos creció con la comunidad de programación.

    Por lo tanto, $ es sólo un nombre de variable. No hay ninguna diferencia entre:

    function foo ($) {alert($)}

    y

    function foo (x) {alert(x)}

    Es sólo el nombre elegido para el parámetro. Sin embargo, la especificación, se sugiere fuertemente que $ no debe ser utilizado por el código escrito por los seres humanos. Está bien para el equipo de código generado (un coffeescript compilador, por ejemplo), pero no aceptar para regular las secuencias de comandos. Por otro lado se recomienda fuertemente en scripts que utilizan jQuery que $ siempre hacen referencia al objeto jQuery (que por cierto también pasa a ser una función, que está bien en javascript ya que las funciones son objetos).

    Ya que está escrito de jQuery el significado de function ($) es una función anónima que acepta un argumento y el argumento de lo que se espera es un objeto jQuery.

    ¿Por qué debería incluir la ventana de documento y definido como argumentos de la función($)?

    Posiblemente, uno de los errores de diseño en javascript es la falta de apoyo de constantes y/o inmutable/protegido variables/objetos. Como tal, window, document y undefined en realidad son regulares variables globales – cualquier persona puede reasignar a nada.

    La siguiente es una locura, pero válido el código javascript:

    window = 42;

    No sane programador, pero no es posible no es menos. El jQuery que los desarrolladores estaban muy preocupados por esto y por lo jQuery intenta su mejor para pasar el real window, document y undefined en plugins en caso de que alguien es lo suficientemente loco como para hacer locuras.

    Una de las características de javascript es que los argumentos de la función reemplazar las variables globales. Así que si alguna de las variables anteriores ha sido secuestrado por alguien que ellos son reasignados a sus nombres propios en la función.

    Si lo hago, ¿cómo puedo acceder a la ventana real y objetos de documento?

    Que se espera que pase la correcta window, document y undefined como argumentos con nombre window, document y undefined en la función. Haciendo cualquier otra cosa significa que usted ya no tendrá acceso a la window, document y undefined objetos.

    Hay locos soluciones que usted puede hacer para intentar ir a tomar una bodega de la window objeto (que también se conoce como el objeto global) y, desde allí, usted puede conseguir un asimiento de document. El código jQuery es en realidad una solución para volver undefined en caso de que éste ha sido secuestrado.

    indefinido qué, y por qué?

    Como usted bien dijo. undefined es el valor de javascript le da a las cosas que se declaran pero no tienen valores asignados a ellos. Pero en javascript undefined es sólo una variable global. Si no la toque inicialmente tiene el valor de undefined (lógica circular, lo sé). Pero puede ser modificado:

    undefined = 'boom!';

    Y a partir de ahora todas las variables no definidas, tendrá el valor de "boom!". La última especificación del lenguaje javascript en realidad no permite reasignar a los indefinidos pero que a día de hoy sólo Safari hace esto.

    De nuevo, no sane programador ello.

    • Diciendo: «los argumentos de la función reemplazar las variables globales» se infiere que cambiar sus valores. Mejor decir que «sombra» o similar jerga (a menos que usted desea conseguir en explicar identificador de resolución en el ámbito de la cadena).
    • Por favor hacer llegar a explicar identificador de resolución en el ámbito de la cadena. 🙂
    • Me parece que a la hora de explicar a los novatos en mi equipo, el uso de términos como «sombra» de los confunde un poco. A través de los años yo solo les digo que las variables locales reemplazar globals y hasta ahora todos entendemos que la simple declaración más clara que hace más estrictamente correcto.
  4. 0

    La inclusión de un identificador en una lista de parámetros es efectivamente el mismo que declarar la variable en el cuerpo de la función, por ejemplo,

    function bar(foo) {
    }

    es equivalente a

    function bar(foo) {
      var foo;
    }

    pero, por supuesto, usted acaba de hacer el primero si quieres pasar un valor a foo.

    La razón principal para hacer:

    (function($) {
        //use $ here instead of jQuery
    }(jQuery));

    es que cuando jQuery fue puesto en libertad, Prototype.js ya había estado utilizando «$» como un identificador para su función principal durante algún tiempo. El modelo anterior permite jQuery y prototype.js para ser utilizado en la misma página, el uso de «$» como un identificador para diferentes cosas.

    Pasando en documento y ventana es, en el mejor, un micro de optimización que tiene poco beneficio. No ofrece protección en contra de que se asignan valores diferentes a los esperados. Simplemente no se molestan y uso ventana y documento dentro de la función global de los identificadores.

    Incluyendo indefinido en los parámetros y no pasa de un valor no es una forma razonable de garantizar indefinido realmente es indefinido, ya que puede verse afectada si un valor es accidentalmente pasado. La forma más segura es:

    (function() {
        var undefined;
        ...
    }());

    Ahora son ciertos que indefinido en el ámbito de la función realmente es indefinido. O si quieres una asignación:

    (function() {
        var undefined = void 0;
        ...
    }());

    Pero que se acaba de escribir.

Dejar respuesta

Please enter your comment!
Please enter your name here