- Notifications
You must be signed in to change notification settings - Fork1
fpmweb/javascript-style-guide
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Basat en:# Airbnb JavaScript Style Guide() {
Un enfoc raonable per JavaScript
- Tipus
- Objectes
- Array
- Cadenes de Text
- Funcions
- Propietats
- Variables
- Hoisting
- Expresions condicionals i igualtat
- Blocs
- Comentaris
- Espais en blanc
- Comes
- Punts i comes
- Casting de Tipus i os & Coerció
- Convencions de nomenclatura
- Funcions d'Accés
- Constructors
- Events
- Móduls
- jQuery
- Compatibilitat amb ES5
- Proves
- Rendiment
- Recursos
- En la cancha
- Traduccions
- La guia de la Guia d'Estil JavaScript
- Col·laboradors
- Llicència
Primitius: Quan accedeixes a un tipus primitiu, utilitzes directament el seu valor
stringnumberbooleannullundefined
varfoo=1,bar=foo;bar=9;console.log(foo,bar);// => 1, 9
Complex: Quan accedeixes a un tipus compelx, utilitzes la referencia al seu valor.
objectarrayfunction
varfoo=[1,2],bar=foo;bar[0]=9;console.log(foo[0],bar[0]);// => 9, 9
Utilitzeu la sintaxi literal per la creació d'objectes.
// malamentvaritem=newObject();// bévaritem={};
No utilitzeuparaules reservades com a claus. No funciona amb IE8.Més informació
// malamentvarsuperman={default:{clark:'kent'},private:true};// bévarsuperman={defaults:{clark:'kent'},hidden:true};
Usa sinónimos legibles en lugar de palabras reservadas cuando sean necesarias.
// malamentvarsuperman={class:'alien'};// malamentvarsuperman={klass:'alien'};// bévarsuperman={type:'alien'};
Usa la sintaxis literal para la creación de arreglos
// malamentvaritems=newArray();// bévaritems=[];
Si no conoces la longitud del arreglo entonces usa Array#push.
varsomeStack=[];// malamentsomeStack[someStack.length]='abracadabra';// bésomeStack.push('abracadabra');
Cuando necesites copiar un arreglo usa Array#slice.jsPerf
varlen=items.length,itemsCopy=[],i;// malamentfor(i=0;i<len;i++){itemsCopy[i]=items[i];}// béitemsCopy=items.slice();
Para convertir un objeto"array-like" (similar a un arreglo) a un arreglo, usa Array#slice.
functiontrigger(){varargs=Array.prototype.slice.call(arguments); ...}
Usa comillas simples
''para las cadenas de texto// malamentvarname="Bob Parr";// bévarname='Bob Parr';// malamentvarfullName="Bob "+this.lastName;// bévarfullName='Bob '+this.lastName;
Las cadenas de texto con una longitud mayor a 80 caracteres deben ser escritas en múltiples líneas usando concatenación.
Nota: Cuando se usa sin criterio, las cadenas de texto largas pueden impactar en el desempeño.jsPerf &Discusión
// malamentvarerrorMessage='This is a super long error that was thrown because of Batman. When you stop to think about how Batman had anything to do with this, you would get nowhere fast.';// bévarerrorMessage='This is a super long error that was thrown because\of Batman. When you stop to think about how Batman had anything to do \with this, you would get nowhere fast.';// bévarerrorMessage='This is a super long error that was thrown because'+'of Batman. When you stop to think about how Batman had anything to do '+'with this, you would get nowhere fast.';
Cuando se crea programáticamente una cadena de texto, use Array#join en vez de concatenación. Sobretodo por IE:jsPerf.
varitems,messages,length,i;messages=[{state:'success',message:'This one worked.'},{state:'success',message:'This one worked as well.'},{state:'error',message:'This one did not work.'}];length=messages.length;// malamentfunctioninbox(messages){items='<ul>';for(i=0;i<length;i++){items+='<li>'+messages[i].message+'</li>';}returnitems+'</ul>';}// béfunctioninbox(messages){items=[];for(i=0;i<length;i++){items[i]=messages[i].message;}return'<ul><li>'+items.join('</li><li>')+'</li></ul>';}
Expresiones de función:
// expresion de funcion anonimavaranonymous=function(){returntrue;};// expresion de funcion nombradavarnamed=functionnamed(){returntrue;};// expresion de funcion inmediatamente invocada (IIFE)(function(){console.log('Welcome to the Internet. Please follow me.');})();
Nunca declares una función en un bloque que no sea de función (if, while, etc). En vez de ello, asigna la función a una variable. Los navegadores te permitirán hacerlo pero todos ellos lo interpretarán de modo diferente, lo que es lamentable.
Nota: ECMA-262 define un bloque como una lista de sentencias. Una declaración de función no es una sentencia.Lee la nota de ECMA-262 sobre este inconveniente.
// malamentif(currentUser){functiontest(){console.log('Nope.');}}// bévartest;if(currentUser){test=functiontest(){console.log('Yup.');};}
Nunca nombres a un parámetro como
arguments, esto tendrá precedencia sobre el objetoargumentsque es brindado en cada ámbito de función.// malamentfunctionnope(name,options,arguments){// ...algo...}// béfunctionyup(name,options,args){// ...algo...}
Usa la notación de punto
.cuando accedas a las propiedades.varluke={jedi:true,age:28};// malamentvarisJedi=luke['jedi'];// bévarisJedi=luke.jedi;
Usa la notación subscript
[]cuando accedas a las propiedades con una variable.varluke={jedi:true,age:28};functiongetProp(prop){returnluke[prop];}varisJedi=getProp('jedi');
Siempre usa
varpara declarar variables. No hacerlo resultará en variables globales. Debemos evitar contaminar el espacio global (global namespace). El Capitán Planeta nos advirtió de eso.// malamentsuperPower=newSuperPower();// bévarsuperPower=newSuperPower();
Usa una declaración
varpara múltiples variables y declara cada variable en una nueva línea.// malamentvaritems=getItems();vargoSportsTeam=true;vardragonball='z';// bévaritems=getItems(),goSportsTeam=true,dragonball='z';
Declara a las variables sin asignación al final. Esto es útil cuando necesites asignar una variable luego dependiendo de una de las variables asignadas previamente, lo hace más notorio.
// malamentvari,len,dragonball,items=getItems(),goSportsTeam=true;// malamentvari,items=getItems(),dragonball,goSportsTeam=true,len;// bévaritems=getItems(),goSportsTeam=true,dragonball,length,i;
Asigna las variables al inicio de su ámbito. Esto ayuda a evitar inconvenientes con la declaración de variables y temas relacionados a 'hoisting'.
// malamentfunction(){test();console.log('doing stuff..');//..otras cosas..varname=getName();if(name==='test'){returnfalse;}returnname;}// béfunction(){varname=getName();test();console.log('doing stuff..');//..otras cosas..if(name==='test'){returnfalse;}returnname;}// malamentfunction(){varname=getName();if(!arguments.length){returnfalse;}returntrue;}// béfunction(){if(!arguments.length){returnfalse;}varname=getName();returntrue;}
Las declaraciones de variables son movidas a la parte superior de su ámbito, sin embargo su asignación no.
// sabemos que esto no funcionara (asumiendo// que no hay una variable global notDefined)functionexample(){console.log(notDefined);// => lanza un ReferenceError}// crear una declaracion de variable luego// que referencies a la variable funcionara// por el hoisting. Nota: A la asignacion// del valor `true` no se le aplico hoisting.functionexample(){console.log(declaredButNotAssigned);// => undefinedvardeclaredButNotAssigned=true;}// El interprete hizo hoisting.// Eso significa que nuestro ejemplo// podria ser reescrito como:functionexample(){vardeclaredButNotAssigned;console.log(declaredButNotAssigned);// => undefineddeclaredButNotAssigned=true;}
Expresiones de función anónimas hacen hoisting de su nombre de variable, pero no de la asignación de la función.
functionexample(){console.log(anonymous);// => undefinedanonymous();// => TypeError anonymous is not a functionvaranonymous=function(){console.log('anonymous function expression');};}
Expresiones de función nombradas hacen hoisting de su nombre de variable, pero no del nombre de la función ni del contenido de la función.
functionexample(){console.log(named);// => undefinednamed();// => TypeError named is not a functionsuperPower();// => ReferenceError superPower is not definedvarnamed=functionsuperPower(){console.log('Flying');};}// lo mismo es cierto cuando el nombre// de la funcion es igual al nombre de// la variable.functionexample(){console.log(named);// => undefinednamed();// => TypeError named is not a functionvarnamed=functionnamed(){console.log('named');}}
Las declaraciones de función hacen hoist de su nombre y del contenido de la función.
functionexample(){superPower();// => FlyingfunctionsuperPower(){console.log('Flying');}}
Per més informació llegeixJavaScript Scoping & Hoisting perBen Cherry
Usa
===y!==en vez de==y!=respectivamente.Expresiones condicionales son evaluadas usando coerción con el método
ToBooleany siempre obedecen a estas reglas sencillas:- Objects son evaluados comotrue
- Undefined es evaluado comofalse
- Null es evaluado comofalse
- Booleans son evaluados comoel valor del booleano
- Numbers son evaluados comofalse si+0,-0, oNaN, de otro modotrue
- Strings son evaluados comofalse si es una cadena de texto vacía
'', de otro modo sontrue
if([0]){// true// un arreglo es un objeto, los objetos son evaluados como true}
Usa atajos.
// malamentif(name!==''){// ...stuff...}// béif(name){// ...stuff...}// malamentif(collection.length>0){// ...stuff...}// béif(collection.length){// ...stuff...}
Para más información revisaTruth Equality and JavaScript por Angus Croll
Usa llaves con todos los bloques de múltiples líneas.
// malamentif(test)returnfalse;// béif(test)returnfalse;// béif(test){returnfalse;}// malamentfunction(){returnfalse;}// béfunction(){returnfalse;}
Usa
/** ... */para comentarios de múltiples líneas. Incluye una descripción, especificación de tipos y valores para todos los parámetros y valores de retorno.// malament// make() returns a new element// based on the passed in tag name////@param <String> tag//@return <Element> elementfunctionmake(tag){// ...stuff...returnelement;}// bé/** * make() returns a new element * based on the passed in tag name * *@param <String> tag *@return <Element> element */functionmake(tag){// ...stuff...returnelement;}
Usa
//para comentarios de una sola línea. Ubica los comentarios de una sola línea encima del sujeto comentado. Deja una línea en blanco antes del comentario.// malamentvaractive=true;// is current tab// bé// is current tabvaractive=true;// malamentfunctiongetType(){console.log('fetching type...');// set the default type to 'no type'vartype=this._type||'no type';returntype;}// béfunctiongetType(){console.log('fetching type...');// set the default type to 'no type'vartype=this._type||'no type';returntype;}
Agregando a tus comentarios los prefijos
FIXMEoTODO, ayudará a otros desarrolladores a entender rápidamente si estás apuntando a un problema que precisa ser revisado o si estás sugiriendo una solución al problema que debería ser implementado. Estos son diferentes a comentarios regulares en el sentido que requieren alguna acción. Las acciones sonFIXME -- necesito resolver estooTODO -- necesita implementarse.Usa
// FIXME:para anotar problemas.functionCalculator(){// FIXME: shouldn't use a global heretotal=0;returnthis;}
Usa
// TODO:para anotar soluciones a los problemas.functionCalculator(){// TODO: total should be configurable by an options paramthis.total=0;returnthis;}
**[[⬆ tornar a la Taula del Contingut](#TOC)**## <a name='whitespace'>Espacios en blanco</a>- Usa indentaciones blandas (sin TAB) establecidas en dos espacios. ```javascript // malament function() { ∙∙∙∙var name; } // malament function() { ∙var name; } // bé function() { ∙∙var name; } ```- Deja un espacio antes de la llave de apertura. ```javascript // malament function test(){ console.log('test'); } // bé function test() { console.log('test'); } // malament dog.set('attr',{ age: '1 year', breed: 'Bernese Mountain Dog' }); // bé dog.set('attr', { age: '1 year', breed: 'Bernese Mountain Dog' }); ```- Deja una línea en blanco al final del archivo. ```javascript // malament (function(global) { // ...algo... })(this); ``` ```javascript // bé (function(global) { // ...algo... })(this); ```- Usa indentación cuando uses métodos largos con 'chaining'. ```javascript // malament $('#items').find('.selected').highlight().end().find('.open').updateCount(); // bé $('#items') .find('.selected') .highlight() .end() .find('.open') .updateCount(); // malament var leds = stage.selectAll('.led').data(data).enter().append('svg:svg').class('led', true) .attr('width', (radius + margin) * 2).append('svg:g') .attr('transform', 'translate(' + (radius + margin) + ',' + (radius + margin) + ')') .call(tron.led); // bé var leds = stage.selectAll('.led') .data(data) .enter().append('svg:svg') .class('led', true) .attr('width', (radius + margin) * 2) .append('svg:g') .attr('transform', 'translate(' + (radius + margin) + ',' + (radius + margin) + ')') .call(tron.led); ``` **[[⬆ tornar a la Taula del Contingut](#TOC)**## <a name='commas'>Comas</a>- Comas al inicio de línea: **Nop.** ```javascript // malament var once , upon , aTime; // bé var once, upon, aTime; // malament var hero = { firstName: 'Bob' , lastName: 'Parr' , heroName: 'Mr. Incredible' , superPower: 'strength' }; // bé var hero = { firstName: 'Bob', lastName: 'Parr', heroName: 'Mr. Incredible', superPower: 'strength' }; ```- Coma adicional al final: **Nop.** Esto puede provocar problemas en IE6/7 o IE9 si está en quirksmode. Además, en algunas implementaciones de ES3 se puede aumentar la longitud del arreglo si se tiene una coma adicional al final. Esto fue clarificado en ES5 ([fuente](http://es5.github.io/#D)):> La Edición 5 aclara el hecho de que dejar una coma al final de un ArrayInitialiser (inicialización de un arreglo) no aumenta la longitud del arreglo. Esto no es un cambio semántico a la Edición 3 pero algunas implementaciones tal vez malinterpretaron esto. ```javascript // malament var hero = { firstName: 'Kevin', lastName: 'Flynn', }; var heroes = [ 'Batman', 'Superman', ]; // bé var hero = { firstName: 'Kevin', lastName: 'Flynn' }; var heroes = [ 'Batman', 'Superman' ]; ``` **[[⬆ tornar a la Taula del Contingut](#TOC)**## <a name='semicolons'>Puntos y Comas</a>- **Sip.** ```javascript // malament (function() { var name = 'Skywalker' return name })() // bé (function() { var name = 'Skywalker'; return name; })(); // bé ;(function() { var name = 'Skywalker'; return name; })(); ``` **[[⬆ tornar a la Taula del Contingut](#TOC)**## <a name='type-coercion'>Casting de Tipos & Coerción</a>- Ejecuta coerción al inicio de una sentencia.- Strings: ```javascript // => this.reviewScore = 9; // malament var totalScore = this.reviewScore + ''; // bé var totalScore = '' + this.reviewScore; // malament var totalScore = '' + this.reviewScore + ' total score'; // bé var totalScore = this.reviewScore + ' total score'; ```- Usa `parseInt` para números y siempre con la base numérica para el casting de tipo. ```javascript var inputValue = '4'; // malament var val = new Number(inputValue); // malament var val = +inputValue; // malament var val = inputValue >> 0; // malament var val = parseInt(inputValue); // bé var val = Number(inputValue); // bé var val = parseInt(inputValue, 10); ```- Si por alguna razón estás haciendo algo salvaje y `parseInt` es un cuello de botella por lo que necesitaste usar Bitshift por [razones de desempeño](http://jsperf.com/coercion-vs-casting/3), deja un comentario explicando qué y porqué lo estás haciendo.- **Nota:** Ten mucho cuidado al hacer operaciones de Bitshift. En Javascript los números son representados como [valores de 64-bit](http://es5.github.io/#x4.3.19), sin embargo las operaciones de Bitshift siempre retornan un entero de 32-bits ([fuente](http://es5.github.io/#x11.7)). Bitshift puede presentarnos un comportamiento inesperado para valores enteros mayores a 32 bits. [Discusión](https://github.com/airbnb/javascript/issues/109) ```javascript // bé /** * parseInt was the reason my code was slow. * Bitshifting the String to coerce it to a * Number made it a lot faster. */ var val = inputValue >> 0; ```- Booleans: ```javascript var age = 0; // mal var hasAge = new Boolean(age); // bé var hasAge = Boolean(age); // bé var hasAge = !!age; ``` **[[⬆ tornar a la Taula del Contingut](#TOC)**## <a name='naming-conventions'>Convenciones de nomenclatura</a>- Evita nombres de una sola letra. Sé descriptivo con tus nombres. ```javascript // malament function q() { // ...algo... } // bé function query() { // ...algo... } ```- Usa camelCase cuando nombres tus objetos, funciones e instancias. ```javascript // malament var OBJEcttsssss = {}; var this_is_my_object = {}; function c() {}; var u = new user({ name: 'Bob Parr' }); // bé var thisIsMyObject = {}; function thisIsMyFunction() {}; var user = new User({ name: 'Bob Parr' }); ```- Usa PascalCase cuando nombres constructores o clases. ```javascript // malament function user(options) { this.name = options.name; } var bad = new user({ name: 'nope' }); // bé function User(options) { this.name = options.name; } var good = new User({ name: 'yup' }); ```- Usa un guión bajo `_` adelante de la variable cuando nombres propiedades privadas. ```javascript // malament this.__firstName__ = 'Panda'; this.firstName_ = 'Panda'; // bé this._firstName = 'Panda'; ```- Cuando guardes una referencia a `this` usa `_this`. ```javascript // malament function() { var self = this; return function() { console.log(self); }; } // malament function() { var that = this; return function() { console.log(that); }; } // bé function() { var _this = this; return function() { console.log(_this); }; } ```- Nombra tus funciones. Esto será de ayuda cuando hagas seguimiento de la pila de llamadas (e.g. en caso de errores). ```javascript // malament var log = function(msg) { console.log(msg); }; // bé var log = function log(msg) { console.log(msg); }; ``` **[[⬆ tornar a la Taula del Contingut](#TOC)**## <a name='accessors'>Funciones de Acceso</a>- Funciones de acceso para las propiedades no son requeridas.- Si creas funciones de acceso usa getVal() y setVal('hello'). ```javascript // malament dragon.age(); // bé dragon.getAge(); // malament dragon.age(25); // bé dragon.setAge(25); ```- Si la propiedad es un booleano, usa isVal() o hasVal(). ```javascript // malament if (!dragon.age()) { return false; } // bé if (!dragon.hasAge()) { return false; } ```- Está bien crear funciones get() y set(), pero sé consistente. ```javascript function Jedi(options) { options || (options = {}); var lightsaber = options.lightsaber || 'blue'; this.set('lightsaber', lightsaber); } Jedi.prototype.set = function(key, val) { this[key] = val; }; Jedi.prototype.get = function(key) { return this[key]; }; ``` **[[⬆ tornar a la Taula del Contingut](#TOC)**## <a name='constructors'>Constructores</a>- Asigna métodos al objeto prototype, en vez de sobreescribir prototype con un nuevo objeto. La sobreescritura de prototype hace la herencia imposible: ¡reseteando prototype sobreescribirás la base! ```javascript function Jedi() { console.log('new jedi'); } // malament Jedi.prototype = { fight: function fight() { console.log('fighting'); }, block: function block() { console.log('blocking'); } }; // bé Jedi.prototype.fight = function fight() { console.log('fighting'); }; Jedi.prototype.block = function block() { console.log('blocking'); }; ```- Métodos pueden retornar `this` para ayudar con el encadenamiento de métodos (chaining). ```javascript // malament Jedi.prototype.jump = function() { this.jumping = true; return true; }; Jedi.prototype.setHeight = function(height) { this.height = height; }; var luke = new Jedi(); luke.jump(); // => true luke.setHeight(20) // => undefined // bé Jedi.prototype.jump = function() { this.jumping = true; return this; }; Jedi.prototype.setHeight = function(height) { this.height = height; return this; }; var luke = new Jedi(); luke.jump() .setHeight(20); ```- Está bien escribir un método toString() personalizado, solo asegúrate que funcione correctamente y no cause efectos colaterales. ```javascript function Jedi(options) { options || (options = {}); this.name = options.name || 'no name'; } Jedi.prototype.getName = function getName() { return this.name; }; Jedi.prototype.toString = function toString() { return 'Jedi - ' + this.getName(); }; ``` **[[⬆ tornar a la Taula del Contingut](#TOC)**## <a name='events'>Eventos</a>- Cuando envies paquetes de datos a los eventos (ya sea con eventos del DOM o algo propietario como los eventos de Backbone), pasa un mapa en vez de un valor directo. Esto permitirá a un próximo colaborador a agregar más datos al paquete de datos sin que tenga que encontrar o actualizar un handler para cada evento. Por ejemplo, en vez de: ```js // malament $(this).trigger('listingUpdated', listing.id); ... $(this).on('listingUpdated', function(e, listingId) { // hacer algo con listingId }); ``` prefiere: ```js // bé $(this).trigger('listingUpdated', { listingId : listing.id }); ... $(this).on('listingUpdated', function(e, data) { // hacer algo con data.listingId }); ```**[[⬆ tornar a la Taula del Contingut](#TOC)**## <a name='modules'>Módulos</a>- El módulo debe empezar con un `!`. Esto asegura que si un módulo mal formado olvide incluir al final un punto y coma, no hayan errores en producción cuando los scripts sean concatenados. [Explicación](https://github.com/airbnb/javascript/issues/44#issuecomment-13063933)- El archivo debe ser nombrado con camelCase, residir en un folder con el mismo nombre, y corresponder al nombre de la función a exportar.- Agrega un método noConflict() que reestablezca el módulo exportado a la versión anterior y retorne este módulo (para ser asignado a una variable).- Siempre declara `'use strict';` al inicio de cada módulo. ```javascript // fancyInput/fancyInput.js !function(global) { 'use strict'; var previousFancyInput = global.FancyInput; function FancyInput(options) { this.options = options || {}; } FancyInput.noConflict = function noConflict() { global.FancyInput = previousFancyInput; return FancyInput; }; global.FancyInput = FancyInput; }(this); ``` **[[⬆ tornar a la Taula del Contingut](#TOC)**## <a name='jquery'>jQuery</a>- Nombre las variables de objetos jQuery con un prefijo `$`. ```javascript // malament var sidebar = $('.sidebar'); // bé var $sidebar = $('.sidebar'); ```- Guarde en variables los lookups de jQuery que se necesiten posteriormente. ```javascript // malament function setSidebar() { $('.sidebar').hide(); // ...algo... $('.sidebar').css({ 'background-color': 'pink' }); } // bé function setSidebar() { var $sidebar = $('.sidebar'); $sidebar.hide(); // ...algo... $sidebar.css({ 'background-color': 'pink' }); } ```- Para consultas de elementos DOM usa el modo Cascada `$('.sidebar ul')` o parent > child `$('.sidebar > ul')`. [jsPerf](http://jsperf.com/jquery-find-vs-context-sel/16)- Usa `find` solo con consultas guardadas en variables previamente. ```javascript // malament $('ul', '.sidebar').hide(); // malament $('.sidebar').find('ul').hide(); // bé $('.sidebar ul').hide(); // bé $('.sidebar > ul').hide(); // bé $sidebar.find('ul'); ``` **[[⬆ tornar a la Taula del Contingut](#TOC)**## <a name='es5'>Compatibilidad con ECMAScript 5</a>- Revisa la [tabla de compatibilidad](http://kangax.github.com/es5-compat-table/) de ES5 de [Kangax](https://twitter.com/kangax/).**[[⬆]](#TOC)**## <a name='testing'>Pruebas</a>- **Sip**. ```javascript function() { return true; } ``` **[[⬆ tornar a la Taula del Contingut](#TOC)**## <a name='performance'>Desempeño</a>- [On Layout & Web Performance](http://kellegous.com/j/2013/01/26/layout-performance/)- [String vs Array Concat](http://jsperf.com/string-vs-array-concat/2)- [Try/Catch Cost In a Loop](http://jsperf.com/try-catch-in-loop-cost)- [Bang Function](http://jsperf.com/bang-function)- [jQuery Find vs Context, Selector](http://jsperf.com/jquery-find-vs-context-sel/13)- [innerHTML vs textContent for script text](http://jsperf.com/innerhtml-vs-textcontent-for-script-text)- [Long String Concatenation](http://jsperf.com/ya-string-concat)- Loading...**[[⬆ tornar a la Taula del Contingut](#TOC)**## <a name='resources'>Recursos</a>**Lee esto**- [Annotated ECMAScript 5.1](http://es5.github.com/)**Otras guías de estilo**- [Google JavaScript Style Guide](http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml) (Guía de Estilo de Javascript de Google)- [jQuery Core Style Guidelines](http://docs.jquery.com/JQuery_Core_Style_Guidelines) (Lineamientos de Estilo con el núcleo de jQuery)- [Principles of Writing Consistent, Idiomatic JavaScript](https://github.com/rwldrn/idiomatic.js/) (Idiomatic #"hidden" data-csrf="true" value="/tOCmcgT++AcmJwHIQCsgZyvxx4BsCuk1kTE8bClwnsAPWpllT6NekzMp+8TN4tsWavLE9MjI3b82hmATTxx4Q==" />About
Guia d'estil en JavaScript
Resources
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Releases
Packages0
Uh oh!
There was an error while loading.Please reload this page.
[8]ページ先頭