Skip to content

Latest commit

History

History
1524 lines (1122 loc) · 39.4 KB

File metadata and controls

1524 lines (1122 loc) · 39.4 KB

원문:https://github.com/airbnb/javascript

Airbnb JavaScript 스타일 가이드() {

  1. Types
  2. Objects
  3. Arrays
  4. Strings
  5. Functions
  6. Properties
  7. Variables
  8. Hoisting
  9. Conditional Expressions & Equality
  10. Blocks
  11. Comments
  12. Whitespace
  13. Commas
  14. Semicolons
  15. Type Casting & Coercion
  16. Naming Conventions
  17. Accessors
  18. Constructors
  19. Events
  20. Modules
  21. jQuery
  22. ES5 Compatibility
  23. Testing
  24. Performance
  25. Resources
  26. In the Wild
  27. Translation
  28. The JavaScript Style Guide Guide
  29. Contributors
  30. License
  • Primitives: primitive type은 그 값을 직접 조작합니다.

    • string
    • number
    • boolean
    • null
    • undefined
    varfoo=1,bar=foo;bar=9;console.log(foo,bar);// => 1, 9
  • Complex: 참조형(Complex)은 참조를 통해 값을 조작합니다.

    • object
    • array
    • function
    varfoo=[1,2],bar=foo;bar[0]=9;console.log(foo[0],bar[0]);// => 9, 9

    [↑]

  • Object를 만들 때는 리터럴 구문을 사용하십시오.

    // badvaritem=newObject();// goodvaritem={};
  • 예약어(reserved words)를 키로 사용하지 마십시오. 이것은 IE8에서 동작하지 않습니다. More info

    // badvarsuperman={default: {clark: 'kent'},private: true};// goodvarsuperman={defaults: {clark: 'kent'},hidden: true};
  • 예약어 대신 알기 쉬운 동의어(readable synonyms)를 사용하십시오.

    // badvarsuperman={class: 'alien'};// badvarsuperman={klass: 'alien'};// goodvarsuperman={type: 'alien'};

    [↑]

  • 배열을 만들 때 리터럴 구문을 사용하십시오.

    // badvaritems=newArray();// goodvaritems=[];
  • 길이를 알 수없는 경우는 Array#push를 사용하십시오.

    varsomeStack=[];// badsomeStack[someStack.length]='abracadabra';// goodsomeStack.push('abracadabra');
  • 배열을 복사 할 필요가있는 경우 Array#slice를 사용하십시오. jsPerf

    varlen=items.length,itemsCopy=[],i;// badfor(i=0;i<len;i++){itemsCopy[i]=items[i];}// gooditemsCopy=items.slice();
  • Array와 비슷한(Array-Like)한 Object를 Array에 변환하는 경우는 Array#slice를 사용하십시오.

    functiontrigger(){varargs=Array.prototype.slice.call(arguments);
    ...
    }

[↑]

  • 문자열은 작은 따옴표''를 사용하십시오.

    // badvarname="Bob Parr";// goodvarname='Bob Parr';// badvarfullName="Bob "+this.lastName;// goodvarfullName='Bob '+this.lastName;
  • 80 문자 이상의 문자열은 문자열 연결을 사용하여 여러 줄에 걸쳐 기술 할 필요가 있습니다.

  • Note : 문자열 연결을 많이하면 성능에 영향을 줄 수 있습니다. jsPerf & Discussion

    // badvarerrorMessage='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.';// badvarerrorMessage='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.';// goodvarerrorMessage='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.';
  • 프로그램에서 문자열을 생성 할 필요가 있는 경우 (특히 IE는) 문자열 연결 대신 Array#join을 사용하십시오. 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;// badfunctioninbox(messages){items='<ul>';for(i=0;i<length;i++){items+='<li>'+messages[i].message+'</li>';}returnitems+'</ul>';}// goodfunctioninbox(messages){items=[];for(i=0;i<length;i++){items[i]=messages[i].message;}return'<ul><li>'+items.join('</li><li>')+'</li></ul>';}

    [↑]

  • 함수식(Function expressions)

    // 익명함수식(anonymous function expression)varanonymous=function(){returntrue;};// 명명된 함수식(named function expression)varnamed=functionnamed(){returntrue;};// 즉시실행 함수식(immediately-invoked function expression (IIFE))(function(){console.log('Welcome to the Internet. Please follow me.');})();
  • (if 및 while 등) 블록 내에서 변수에 함수를 할당하는 대신 함수를 선언하지 마십시오. 브라우저는 허용하지만 (마치 'bad news bears'처럼) 모두 다른 방식으로 해석됩니다.

  • Note: ECMA-262에서는block은 statements의 목록에 정의되어 있습니다 만, 함수 선언은 statements가 없습니다. 이 문제는 ECMA-262의 설명을 참조하십시오. .

    // badif(currentUser){functiontest(){console.log('Nope.');}}// goodvartest;if(currentUser){test=functiontest(){console.log('Yup.');};}
  • 매개 변수(parameter)에 arguments를 절대 지정하지 마십시오. 이것은 함수 범위로 전달 될arguments객체의 참조를 덮어 쓸 것입니다.

    // badfunctionnope(name,options,arguments){// ...stuff...}// goodfunctionyup(name,options,args){// ...stuff...}

    [↑]

  • 속성에 액세스하려면 도트.를 사용하십시오.

    varluke={jedi: true,age: 28};// badvarisJedi=luke['jedi'];// goodvarisJedi=luke.jedi;
  • 변수를 사용하여 속성에 접근하려면 대괄호[]을 사용하십시오.

    varluke={jedi: true,age: 28};functiongetProp(prop){returnluke[prop];}varisJedi=getProp('jedi');

    [↑]

  • 변수를 선언 할 때는 항상 var를 사용하십시오. 그렇지 않으면 전역 변수로 선언됩니다. 전역 네임 스페이스를 오염시키지 않도록 Captain Planet도 경고하고 있습니다.

    // badsuperPower=newSuperPower();// goodvarsuperPower=newSuperPower();
  • 여러 변수를 선언하려면 하나의 var를 사용하여 변수마다 줄바꿈하여 선언하십시오.

    // badvaritems=getItems();vargoSportsTeam=true;vardragonball='z';// goodvaritems=getItems(),goSportsTeam=true,dragonball='z';
  • 정의되지 않은 변수를 마지막으로 선언하십시오. 이것은 나중에 이미 할당된 변수 중 하나를 지정해야하는 경우에 유용합니다.

    // badvari,len,dragonball,items=getItems(),goSportsTeam=true;// badvari,items=getItems(),dragonball,goSportsTeam=true,len;// goodvaritems=getItems(),goSportsTeam=true,dragonball,length,i;
  • 변수의 할당은 스코프의 시작 부분에서 해주십시오. 이것은 변수 선언과 Hoisting 관련 문제를 해결합니다.

    // badfunction(){test();console.log('doing stuff..');//..other stuff..varname=getName();if(name==='test'){returnfalse;}returnname;}// goodfunction(){varname=getName();test();console.log('doing stuff..');//..other stuff..if(name==='test'){returnfalse;}returnname;}// badfunction(){varname=getName();if(!arguments.length){returnfalse;}returntrue;}// goodfunction(){if(!arguments.length){returnfalse;}varname=getName();returntrue;}

    [↑]

  • 해당 스코프의 시작 부분에 Hoist된 변수선언은 할당되지 않습니다.

    // (notDefined가 전역 변수에 존재하지 않는다고 가정했을 경우)// 이것은 동작하지 않습니다.functionexample(){console.log(notDefined);// => throws a ReferenceError}// 그 변수를 참조하는 코드 후에 그 변수를 선언 한 경우// 변수가 Hoist된 상태에서 작동합니다.// Note : `true`라는 값 자체는 Hoist되지 않습니다.functionexample(){console.log(declaredButNotAssigned);// => undefinedvardeclaredButNotAssigned=true;}// 인터 프린터는 변수 선언을 스코프의 시작 부분에 Hoist합니다.// 위의 예는 다음과 같이 다시 작성할 수 있습니다.functionexample(){vardeclaredButNotAssigned;console.log(declaredButNotAssigned);// => undefineddeclaredButNotAssigned=true;}
  • 익명 함수의 경우 함수가 할당되기 전에 변수가 Hoist될 수 있습니다.

    functionexample(){console.log(anonymous);// => undefinedanonymous();// => TypeError anonymous is not a functionvaranonymous=function(){console.log('anonymous function expression');};}
  • 명명 된 함수의 경우도 마찬가지로 변수가 Hoist될 수 있습니다. 함수 이름과 함수 본체는 Hoist되지 않습니다.

    functionexample(){console.log(named);// => undefinednamed();// => TypeError named is not a functionsuperPower();// => ReferenceError superPower is not definedvarnamed=functionsuperPower(){console.log('Flying');};}// 함수이름과 변수이름이 같은 경우에도 같은 일이 일어납니다.functionexample(){console.log(named);// => undefinednamed();// => TypeError named is not a functionvarnamed=functionnamed(){console.log('named');}}
  • 함수 선언은 함수이름과 함수본문이 Hoist됩니다.

    functionexample(){superPower();// => FlyingfunctionsuperPower(){console.log('Flying');}}
  • 더 자세한 정보는 Ben CherryJavaScript Scoping & Hoisting를 참조하십시오.

    [↑]

  • ==!= 보다는 ===!== 를 사용해 주십시오

  • 조건식은ToBoolean 메소드에 의해 엄밀하게 비교됩니다. 항상 이 간단한 규칙에 따라 주십시오.

    • Objectstrue 로 평가됩니다.
    • undefinedfalse 로 평가됩니다.
    • nullfalse 로 평가됩니다.
    • Booleansboolean형의 값 으로 평가됩니다.
    • Numberstrue 로 평가됩니다. 하지만 +0, -0, or NaN 의 경우는 false 입니다.
    • Stringstrue 로 평가됩니다. 하지만 빈문자 '' 의 경우는 false 입니다.
    if([0]){// true// Array는 Object 이므로 true 로 평가됩니다.}
  • 짧은형식을 사용하십시오.

    // badif(name!==''){// ...stuff...}// goodif(name){// ...stuff...}// badif(collection.length>0){// ...stuff...}// goodif(collection.length){// ...stuff...}
  • 더 자세한 정보는 Angus Croll 의 Truth Equality and JavaScript를 참고해 주십시오.

    [↑]

  • 복수행 블록은 중괄호 ({})를 사용하십시오.

    // badif(test)returnfalse;// goodif(test)returnfalse;// goodif(test){returnfalse;}// badfunction(){returnfalse;}// goodfunction(){returnfalse;}

    [↑]

  • 복수행의 코멘트는 /** ... */ 를 사용해 주십시오. 그 안에는 설명과 모든 매개 변수와 반환 값에 대한 형식과 값을 설명합니다.

    // bad// make() returns a new element// based on the passed in tag name//// @param <String> tag// @return <Element> elementfunctionmake(tag){// ...stuff...returnelement;}// good/** * make() returns a new element * based on the passed in tag name * * @param <String> tag * @return <Element> element */functionmake(tag){// ...stuff...returnelement;}
  • 한 줄 주석에는//를 사용하십시오. 코멘트를 추가하고 싶은 코드의 상단에 작성하십시오. 또한 주석 앞에 빈 줄을 넣어주십시오.

    // badvaractive=true;// is current tab// good// is current tabvaractive=true;// badfunctiongetType(){console.log('fetching type...');// set the default type to 'no type'vartype=this._type||'no type';returntype;}// goodfunctiongetType(){console.log('fetching type...');// set the default type to 'no type'vartype=this._type||'no type';returntype;}
  • 문제를 지적하고 재고를 촉구하거나 문제에 대한 해결책을 제시하는 등 의견의 앞에 FIXMETODO를 붙이는 것으로 다른 개발자의 빠른 이해를 도울 수 있습니다. 이러한 어떤 액션을 동반한다는 의미에서 일반 코멘트와는 다릅니다. 액션은 FIXME - 해결책이 필요 또는 TODO - 구현이 필요 입니다.

  • 문제에 대한 코멘트로 // FIXME :를 사용하십시오.

    functionCalculator(){// FIXME: 전역 변수를 사용해서는 안됩니다.total=0;returnthis;}
  • 문제 해결책에 대한 코멘트로 // TODO :를 사용하십시오.

    functionCalculator(){// TODO: total은 옵션 매개 변수로 설정되어야 함.this.total=0;returnthis;}

[↑]

  • 탭에는 공백 2개를 설정하십시오.

    // badfunction(){∙∙∙∙varname;}// badfunction(){∙varname;}// goodfunction(){∙∙varname;}
  • 중괄호({})의 앞에 공백을 하나 넣어주십시오.

    // badfunctiontest(){console.log('test');}// goodfunctiontest(){console.log('test');}// baddog.set('attr',{age: '1 year',breed: 'Bernese Mountain Dog'});// gooddog.set('attr',{age: '1 year',breed: 'Bernese Mountain Dog'});
  • 파일의 마지막에는 빈 줄을 하나 넣어주십시오.

    // bad(function(global){// ...stuff...})(this);
    // good(function(global){// ...stuff...})(this);
  • 메소드 체인이 길어지는 경우 적절히 들여쓰기(indentation) 하십시오.

    // bad$('#items').find('.selected').highlight().end().find('.open').updateCount();// good$('#items').find('.selected').highlight().end().find('.open').updateCount();// badvarleds=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);// goodvarleds=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);

    [↑]

  • 선두의 comma는 하지마십시오.

    // badvaronce,upon,aTime;// goodvaronce,upon,aTime;// badvarhero={firstName: 'Bob',lastName: 'Parr',heroName: 'Mr. Incredible',superPower: 'strength'};// goodvarhero={firstName: 'Bob',lastName: 'Parr',heroName: 'Mr. Incredible',superPower: 'strength'};
  • 말미의 불필요한 쉼표도 하지 마십시오. 이것은 IE6/7과 quirksmode의 IE9에서 문제를 일으킬 수 있습니다. 또한 ES3의 일부 구현에서 불필요한 쉼표가 있는 경우, 배열 길이를 추가합니다. 이것은 ES5에서 분명해졌습니다.(source):

    제 5 판에서는 말미의 불필요한 쉼표가 있는 ArrayInitialiser (배열 초기화 연산자)라도 배열에 길이를 추가하지 않는다는 사실을 명확히하고 있습니다. 이것은 제 3 판에서 의미적인 변경은 아닙니다만, 일부의 구현은 이전부터 이것을 오해하고 있었을지도 모릅니다.

    // badvarhero={firstName: 'Kevin',lastName: 'Flynn',};varheroes=['Batman','Superman',];// goodvarhero={firstName: 'Kevin',lastName: 'Flynn'};varheroes=['Batman','Superman'];

    [↑]

  • 네!(Yup.)

    // bad(function(){varname='Skywalker'returnname})()// good(function(){varname='Skywalker';returnname;})();// good;(function(){varname='Skywalker';returnname;})();

    [↑]

  • 문의 시작 부분에서 형을 강제합니다.

  • Strings:

    // => this.reviewScore = 9;// badvartotalScore=this.reviewScore+'';// goodvartotalScore=''+this.reviewScore;// badvartotalScore=''+this.reviewScore+' total score';// goodvartotalScore=this.reviewScore+' total score';
  • 숫자는parseInt를 사용하십시오. 항상 형변환을 위한 기수(radix)를 인수로 전달하십시오.

    varinputValue='4';// badvarval=newNumber(inputValue);// badvarval=+inputValue;// badvarval=inputValue>>0;// badvarval=parseInt(inputValue);// goodvarval=Number(inputValue);// goodvarval=parseInt(inputValue,10);
  • 어떤 이유에 의해 parseInt 가 병목이 되고, 성능적인 이유로 Bitshift를 사용할 필요가 있을 경우, 하려고 하는것에 대해, why(왜)와 what(무엇)의 설명을 코멘트로 남겨주십시오.

    // good/** * parseInt가 병목을 일으키므로 * Bitshift로 문자열을 수치로 강제적으로 변환하는 방법으로 * 성능을 개선시킵니다. */varval=inputValue>>0;
  • Booleans:

    varage=0;// badvarhasAge=newBoolean(age);// goodvarhasAge=Boolean(age);// goodvarhasAge=!!age;

    [↑]

  • 한문자 이름은 피하십시오. 이름에서 의도를 읽을 수 있도록 하십시오.

    // badfunctionq(){// ...stuff...}// goodfunctionquery(){// ..stuff..}
  • Object, 함수, 그리고 인스턴스로는 camelCase를 사용하십시오.

    // badvarOBJEcttsssss={};varthis_is_my_object={};varthis-is-my-object={};functionc(){};varu=newuser({name: 'Bob Parr'});// goodvarthisIsMyObject={};functionthisIsMyFunction(){};varuser=newUser({name: 'Bob Parr'});
  • Class와 생성자에는 PascalCase를 사용하십시오.

    // badfunctionuser(options){this.name=options.name;}varbad=newuser({name: 'nope'});// goodfunctionUser(options){this.name=options.name;}vargood=newUser({name: 'yup'});
  • private 속성 이름은 밑줄 _ 을 사용하십시오.

    // badthis.__firstName__='Panda';this.firstName_='Panda';// goodthis._firstName='Panda';
  • this의 참조를 저장할 때 _this 를 사용하십시오.

    // badfunction(){varself=this;returnfunction(){console.log(self);};}// badfunction(){varthat=this;returnfunction(){console.log(that);};}// goodfunction(){var_this=this;returnfunction(){console.log(_this);};}
  • 함수에 이름을 붙여주십시오. 이것은 stack traces를 추적하기 쉽게하기 때문입니다.

    // badvarlog=function(msg){console.log(msg);};// goodvarlog=functionlog(msg){console.log(msg);};

    [↑]

  • 속성을 위한 접근자(Accessor) 함수는 필요 없습니다.

  • 접근자 함수가 필요한 경우 getVal() 이나 setVal('hello') 라고 사용합니다.

    // baddragon.age();// gooddragon.getAge();// baddragon.age(25);// gooddragon.setAge(25);
  • 속성이 boolean의 경우 isVal() 이나 hasVal() 라고 사용합니다.

    // badif(!dragon.age()){returnfalse;}// goodif(!dragon.hasAge()){returnfalse;}
  • 일관된다면 get() 이나 set() 이라는 함수를 작성해도 좋습니다.

    functionJedi(options){options||(options={});varlightsaber=options.lightsaber||'blue';this.set('lightsaber',lightsaber);}Jedi.prototype.set=function(key,val){this[key]=val;};Jedi.prototype.get=function(key){returnthis[key];};

    [↑]

  • 새 Object에서 프로토타입을 재정의하는 것이 아니라, 프로토타입 객체에 메서드를 추가해 주십시오. 프로토타입을 재정의하면 상속이 불가능합니다. 프로토타입을 리셋하는것으로 베이스 클래스를 재정의 할 수 있습니다.

    functionJedi(){console.log('new jedi');}// badJedi.prototype={fight: functionfight(){console.log('fighting');},block: functionblock(){console.log('blocking');}};// goodJedi.prototype.fight=functionfight(){console.log('fighting');};Jedi.prototype.block=functionblock(){console.log('blocking');};
  • 메소드의 반환 값으로 this를 반환함으로써 메소드 체인을 할 수 있습니다.

    // badJedi.prototype.jump=function(){this.jumping=true;returntrue;};Jedi.prototype.setHeight=function(height){this.height=height;};varluke=newJedi();luke.jump();// => trueluke.setHeight(20)// => undefined// goodJedi.prototype.jump=function(){this.jumping=true;returnthis;};Jedi.prototype.setHeight=function(height){this.height=height;returnthis;};varluke=newJedi();luke.jump().setHeight(20);
  • 독자적인 toString()을 만들 수도 있지만 올바르게 작동하는지, 부작용이 없는 것만은 확인해 주십시오.

    functionJedi(options){options||(options={});this.name=options.name||'no name';}Jedi.prototype.getName=functiongetName(){returnthis.name;};Jedi.prototype.toString=functiontoString(){return'Jedi - '+this.getName();};

    [↑]

  • (DOM 이벤트나 Backbone events와 같은 고유의) 이벤트 탑재체(payloads)의 값을 전달하는 경우 원시 값(raw value) 대신 해시 인수(hash)를 전달합니다. 이렇게하는 것으로 나중에 개발자가 이벤트와 관련된 모든 핸들러를 찾아 업데이트 하지 않고 이벤트 탑재체(payloads)에 값을 추가 할 수 있습니다. 예를 들어, 이것 대신 :

    // bad$(this).trigger('listingUpdated',listing.id);
    ...
    $(this).on('listingUpdated',function(e,listingId){// do something with listingId});

    이쪽을 선호합니다.:

    // good$(this).trigger('listingUpdated',{listingId : listing.id});
    ...
    $(this).on('listingUpdated',function(e,data){// do something with data.listingId});

[↑]

  • 모듈의 시작은 ! 로 시작하십시오. 이것은 문말에 세미콜론을 넣는것을 잊은 모듈을 연결할때 런타임 오류가 발생하지 않기 때문입니다.

  • 파일 이름은 camelCase를 사용하여 같은 이름의 폴더에 저장해주십시오. 또한 단독으로 공개할 경우 이름을 일치시켜주십시오.

  • noConflict() 라는 명칭으로 (이름이 겹쳐 덮어 써지기 전의) 모듈을 반환하는 메서드를 추가해주십시오.

  • 항상 모듈의 시작 부분에서 'use strict';를 선언해주십시오.

    // fancyInput/fancyInput.js!function(global){'use strict';varpreviousFancyInput=global.FancyInput;functionFancyInput(options){this.options=options||{};}FancyInput.noConflict=functionnoConflict(){global.FancyInput=previousFancyInput;returnFancyInput;};global.FancyInput=FancyInput;}(this);

    [↑]

  • jQuery Object의 변수 앞에는 $을 부여해 주십시오.

    // badvarsidebar=$('.sidebar');// goodvar$sidebar=$('.sidebar');
  • jQuery 쿼리결과를 캐시해주십시오.

    // badfunctionsetSidebar(){$('.sidebar').hide();// ...stuff...$('.sidebar').css({'background-color': 'pink'});}// goodfunctionsetSidebar(){var$sidebar=$('.sidebar');$sidebar.hide();// ...stuff...$sidebar.css({'background-color': 'pink'});}
  • DOM 검색은 Cascading $('.sidebar ul') 이나 parent > child $('.sidebar > ul') 를 사용해주십시오. jsPerf

  • jQuery Object 검색은 스코프가 붙은 find를 사용해주십시오.

    // bad$('ul','.sidebar').hide();// bad$('.sidebar').find('ul').hide();// good$('.sidebar ul').hide();// good$('.sidebar > ul').hide();// good$sidebar.find('ul');

    [↑]

[↑]

  • 네!(Yup.)

    function(){returntrue;}

    [↑]

[↑]

Read This

Other Styleguides

Other Styles

Further Reading

Books

Blogs

[↑]

This is a list of organizations that are using this style guide. Send us a pull request or open an issue and we'll add you to the list.

This style guide is also available in other languages:

(The MIT License)

Copyright (c) 2012 Airbnb

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

[↑]

};

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
javascript-style-guide/es5.md at master · tipjs/javascript-style-guide · GitHub
Skip to content

Latest commit

History

History
1524 lines (1122 loc) · 39.4 KB

File metadata and controls

1524 lines (1122 loc) · 39.4 KB

원문:https://github.com/airbnb/javascript

Airbnb JavaScript 스타일 가이드() {

  1. Types
  2. Objects
  3. Arrays
  4. Strings
  5. Functions
  6. Properties
  7. Variables
  8. Hoisting
  9. Conditional Expressions & Equality
  10. Blocks
  11. Comments
  12. Whitespace
  13. Commas
  14. Semicolons
  15. Type Casting & Coercion
  16. Naming Conventions
  17. Accessors
  18. Constructors
  19. Events
  20. Modules
  21. jQuery
  22. ES5 Compatibility
  23. Testing
  24. Performance
  25. Resources
  26. In the Wild
  27. Translation
  28. The JavaScript Style Guide Guide
  29. Contributors
  30. License
  • Primitives: primitive type은 그 값을 직접 조작합니다.

    • string
    • number
    • boolean
    • null
    • undefined
    varfoo=1,bar=foo;bar=9;console.log(foo,bar);// => 1, 9
  • Complex: 참조형(Complex)은 참조를 통해 값을 조작합니다.

    • object
    • array
    • function
    varfoo=[1,2],bar=foo;bar[0]=9;console.log(foo[0],bar[0]);// => 9, 9

    [↑]

  • Object를 만들 때는 리터럴 구문을 사용하십시오.

    // badvaritem=newObject();// goodvaritem={};
  • 예약어(reserved words)를 키로 사용하지 마십시오. 이것은 IE8에서 동작하지 않습니다. More info

    // badvarsuperman={default: {clark: 'kent'},private: true};// goodvarsuperman={defaults: {clark: 'kent'},hidden: true};
  • 예약어 대신 알기 쉬운 동의어(readable synonyms)를 사용하십시오.

    // badvarsuperman={class: 'alien'};// badvarsuperman={klass: 'alien'};// goodvarsuperman={type: 'alien'};

    [↑]

  • 배열을 만들 때 리터럴 구문을 사용하십시오.

    // badvaritems=newArray();// goodvaritems=[];
  • 길이를 알 수없는 경우는 Array#push를 사용하십시오.

    varsomeStack=[];// badsomeStack[someStack.length]='abracadabra';// goodsomeStack.push('abracadabra');
  • 배열을 복사 할 필요가있는 경우 Array#slice를 사용하십시오. jsPerf

    varlen=items.length,itemsCopy=[],i;// badfor(i=0;i<len;i++){itemsCopy[i]=items[i];}// gooditemsCopy=items.slice();
  • Array와 비슷한(Array-Like)한 Object를 Array에 변환하는 경우는 Array#slice를 사용하십시오.

    functiontrigger(){varargs=Array.prototype.slice.call(arguments);
    ...
    }

[↑]

  • 문자열은 작은 따옴표''를 사용하십시오.

    // badvarname="Bob Parr";// goodvarname='Bob Parr';// badvarfullName="Bob "+this.lastName;// goodvarfullName='Bob '+this.lastName;
  • 80 문자 이상의 문자열은 문자열 연결을 사용하여 여러 줄에 걸쳐 기술 할 필요가 있습니다.

  • Note : 문자열 연결을 많이하면 성능에 영향을 줄 수 있습니다. jsPerf & Discussion

    // badvarerrorMessage='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.';// badvarerrorMessage='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.';// goodvarerrorMessage='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.';
  • 프로그램에서 문자열을 생성 할 필요가 있는 경우 (특히 IE는) 문자열 연결 대신 Array#join을 사용하십시오. 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;// badfunctioninbox(messages){items='<ul>';for(i=0;i<length;i++){items+='<li>'+messages[i].message+'</li>';}returnitems+'</ul>';}// goodfunctioninbox(messages){items=[];for(i=0;i<length;i++){items[i]=messages[i].message;}return'<ul><li>'+items.join('</li><li>')+'</li></ul>';}

    [↑]

  • 함수식(Function expressions)

    // 익명함수식(anonymous function expression)varanonymous=function(){returntrue;};// 명명된 함수식(named function expression)varnamed=functionnamed(){returntrue;};// 즉시실행 함수식(immediately-invoked function expression (IIFE))(function(){console.log('Welcome to the Internet. Please follow me.');})();
  • (if 및 while 등) 블록 내에서 변수에 함수를 할당하는 대신 함수를 선언하지 마십시오. 브라우저는 허용하지만 (마치 'bad news bears'처럼) 모두 다른 방식으로 해석됩니다.

  • Note: ECMA-262에서는block은 statements의 목록에 정의되어 있습니다 만, 함수 선언은 statements가 없습니다. 이 문제는 ECMA-262의 설명을 참조하십시오. .

    // badif(currentUser){functiontest(){console.log('Nope.');}}// goodvartest;if(currentUser){test=functiontest(){console.log('Yup.');};}
  • 매개 변수(parameter)에 arguments를 절대 지정하지 마십시오. 이것은 함수 범위로 전달 될arguments객체의 참조를 덮어 쓸 것입니다.

    // badfunctionnope(name,options,arguments){// ...stuff...}// goodfunctionyup(name,options,args){// ...stuff...}

    [↑]

  • 속성에 액세스하려면 도트.를 사용하십시오.

    varluke={jedi: true,age: 28};// badvarisJedi=luke['jedi'];// goodvarisJedi=luke.jedi;
  • 변수를 사용하여 속성에 접근하려면 대괄호[]을 사용하십시오.

    varluke={jedi: true,age: 28};functiongetProp(prop){returnluke[prop];}varisJedi=getProp('jedi');

    [↑]

  • 변수를 선언 할 때는 항상 var를 사용하십시오. 그렇지 않으면 전역 변수로 선언됩니다. 전역 네임 스페이스를 오염시키지 않도록 Captain Planet도 경고하고 있습니다.

    // badsuperPower=newSuperPower();// goodvarsuperPower=newSuperPower();
  • 여러 변수를 선언하려면 하나의 var를 사용하여 변수마다 줄바꿈하여 선언하십시오.

    // badvaritems=getItems();vargoSportsTeam=true;vardragonball='z';// goodvaritems=getItems(),goSportsTeam=true,dragonball='z';
  • 정의되지 않은 변수를 마지막으로 선언하십시오. 이것은 나중에 이미 할당된 변수 중 하나를 지정해야하는 경우에 유용합니다.

    // badvari,len,dragonball,items=getItems(),goSportsTeam=true;// badvari,items=getItems(),dragonball,goSportsTeam=true,len;// goodvaritems=getItems(),goSportsTeam=true,dragonball,length,i;
  • 변수의 할당은 스코프의 시작 부분에서 해주십시오. 이것은 변수 선언과 Hoisting 관련 문제를 해결합니다.

    // badfunction(){test();console.log('doing stuff..');//..other stuff..varname=getName();if(name==='test'){returnfalse;}returnname;}// goodfunction(){varname=getName();test();console.log('doing stuff..');//..other stuff..if(name==='test'){returnfalse;}returnname;}// badfunction(){varname=getName();if(!arguments.length){returnfalse;}returntrue;}// goodfunction(){if(!arguments.length){returnfalse;}varname=getName();returntrue;}

    [↑]

  • 해당 스코프의 시작 부분에 Hoist된 변수선언은 할당되지 않습니다.

    // (notDefined가 전역 변수에 존재하지 않는다고 가정했을 경우)// 이것은 동작하지 않습니다.functionexample(){console.log(notDefined);// => throws a ReferenceError}// 그 변수를 참조하는 코드 후에 그 변수를 선언 한 경우// 변수가 Hoist된 상태에서 작동합니다.// Note : `true`라는 값 자체는 Hoist되지 않습니다.functionexample(){console.log(declaredButNotAssigned);// => undefinedvardeclaredButNotAssigned=true;}// 인터 프린터는 변수 선언을 스코프의 시작 부분에 Hoist합니다.// 위의 예는 다음과 같이 다시 작성할 수 있습니다.functionexample(){vardeclaredButNotAssigned;console.log(declaredButNotAssigned);// => undefineddeclaredButNotAssigned=true;}
  • 익명 함수의 경우 함수가 할당되기 전에 변수가 Hoist될 수 있습니다.

    functionexample(){console.log(anonymous);// => undefinedanonymous();// => TypeError anonymous is not a functionvaranonymous=function(){console.log('anonymous function expression');};}
  • 명명 된 함수의 경우도 마찬가지로 변수가 Hoist될 수 있습니다. 함수 이름과 함수 본체는 Hoist되지 않습니다.

    functionexample(){console.log(named);// => undefinednamed();// => TypeError named is not a functionsuperPower();// => ReferenceError superPower is not definedvarnamed=functionsuperPower(){console.log('Flying');};}// 함수이름과 변수이름이 같은 경우에도 같은 일이 일어납니다.functionexample(){console.log(named);// => undefinednamed();// => TypeError named is not a functionvarnamed=functionnamed(){console.log('named');}}
  • 함수 선언은 함수이름과 함수본문이 Hoist됩니다.

    functionexample(){superPower();// => FlyingfunctionsuperPower(){console.log('Flying');}}
  • 더 자세한 정보는 Ben CherryJavaScript Scoping & Hoisting를 참조하십시오.

    [↑]

  • ==!= 보다는 ===!== 를 사용해 주십시오

  • 조건식은ToBoolean 메소드에 의해 엄밀하게 비교됩니다. 항상 이 간단한 규칙에 따라 주십시오.

    • Objectstrue 로 평가됩니다.
    • undefinedfalse 로 평가됩니다.
    • nullfalse 로 평가됩니다.
    • Booleansboolean형의 값 으로 평가됩니다.
    • Numberstrue 로 평가됩니다. 하지만 +0, -0, or NaN 의 경우는 false 입니다.
    • Stringstrue 로 평가됩니다. 하지만 빈문자 '' 의 경우는 false 입니다.
    if([0]){// true// Array는 Object 이므로 true 로 평가됩니다.}
  • 짧은형식을 사용하십시오.

    // badif(name!==''){// ...stuff...}// goodif(name){// ...stuff...}// badif(collection.length>0){// ...stuff...}// goodif(collection.length){// ...stuff...}
  • 더 자세한 정보는 Angus Croll 의 Truth Equality and JavaScript를 참고해 주십시오.

    [↑]

  • 복수행 블록은 중괄호 ({})를 사용하십시오.

    // badif(test)returnfalse;// goodif(test)returnfalse;// goodif(test){returnfalse;}// badfunction(){returnfalse;}// goodfunction(){returnfalse;}

    [↑]

  • 복수행의 코멘트는 /** ... */ 를 사용해 주십시오. 그 안에는 설명과 모든 매개 변수와 반환 값에 대한 형식과 값을 설명합니다.

    // bad// make() returns a new element// based on the passed in tag name//// @param <String> tag// @return <Element> elementfunctionmake(tag){// ...stuff...returnelement;}// good/** * make() returns a new element * based on the passed in tag name * * @param <String> tag * @return <Element> element */functionmake(tag){// ...stuff...returnelement;}
  • 한 줄 주석에는//를 사용하십시오. 코멘트를 추가하고 싶은 코드의 상단에 작성하십시오. 또한 주석 앞에 빈 줄을 넣어주십시오.

    // badvaractive=true;// is current tab// good// is current tabvaractive=true;// badfunctiongetType(){console.log('fetching type...');// set the default type to 'no type'vartype=this._type||'no type';returntype;}// goodfunctiongetType(){console.log('fetching type...');// set the default type to 'no type'vartype=this._type||'no type';returntype;}
  • 문제를 지적하고 재고를 촉구하거나 문제에 대한 해결책을 제시하는 등 의견의 앞에 FIXMETODO를 붙이는 것으로 다른 개발자의 빠른 이해를 도울 수 있습니다. 이러한 어떤 액션을 동반한다는 의미에서 일반 코멘트와는 다릅니다. 액션은 FIXME - 해결책이 필요 또는 TODO - 구현이 필요 입니다.

  • 문제에 대한 코멘트로 // FIXME :를 사용하십시오.

    functionCalculator(){// FIXME: 전역 변수를 사용해서는 안됩니다.total=0;returnthis;}
  • 문제 해결책에 대한 코멘트로 // TODO :를 사용하십시오.

    functionCalculator(){// TODO: total은 옵션 매개 변수로 설정되어야 함.this.total=0;returnthis;}

[↑]

  • 탭에는 공백 2개를 설정하십시오.

    // badfunction(){∙∙∙∙varname;}// badfunction(){∙varname;}// goodfunction(){∙∙varname;}
  • 중괄호({})의 앞에 공백을 하나 넣어주십시오.

    // badfunctiontest(){console.log('test');}// goodfunctiontest(){console.log('test');}// baddog.set('attr',{age: '1 year',breed: 'Bernese Mountain Dog'});// gooddog.set('attr',{age: '1 year',breed: 'Bernese Mountain Dog'});
  • 파일의 마지막에는 빈 줄을 하나 넣어주십시오.

    // bad(function(global){// ...stuff...})(this);
    // good(function(global){// ...stuff...})(this);
  • 메소드 체인이 길어지는 경우 적절히 들여쓰기(indentation) 하십시오.

    // bad$('#items').find('.selected').highlight().end().find('.open').updateCount();// good$('#items').find('.selected').highlight().end().find('.open').updateCount();// badvarleds=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);// goodvarleds=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);

    [↑]

  • 선두의 comma는 하지마십시오.

    // badvaronce,upon,aTime;// goodvaronce,upon,aTime;// badvarhero={firstName: 'Bob',lastName: 'Parr',heroName: 'Mr. Incredible',superPower: 'strength'};// goodvarhero={firstName: 'Bob',lastName: 'Parr',heroName: 'Mr. Incredible',superPower: 'strength'};
  • 말미의 불필요한 쉼표도 하지 마십시오. 이것은 IE6/7과 quirksmode의 IE9에서 문제를 일으킬 수 있습니다. 또한 ES3의 일부 구현에서 불필요한 쉼표가 있는 경우, 배열 길이를 추가합니다. 이것은 ES5에서 분명해졌습니다.(source):

    제 5 판에서는 말미의 불필요한 쉼표가 있는 ArrayInitialiser (배열 초기화 연산자)라도 배열에 길이를 추가하지 않는다는 사실을 명확히하고 있습니다. 이것은 제 3 판에서 의미적인 변경은 아닙니다만, 일부의 구현은 이전부터 이것을 오해하고 있었을지도 모릅니다.

    // badvarhero={firstName: 'Kevin',lastName: 'Flynn',};varheroes=['Batman','Superman',];// goodvarhero={firstName: 'Kevin',lastName: 'Flynn'};varheroes=['Batman','Superman'];

    [↑]

  • 네!(Yup.)

    // bad(function(){varname='Skywalker'returnname})()// good(function(){varname='Skywalker';returnname;})();// good;(function(){varname='Skywalker';returnname;})();

    [↑]

  • 문의 시작 부분에서 형을 강제합니다.

  • Strings:

    // => this.reviewScore = 9;// badvartotalScore=this.reviewScore+'';// goodvartotalScore=''+this.reviewScore;// badvartotalScore=''+this.reviewScore+' total score';// goodvartotalScore=this.reviewScore+' total score';
  • 숫자는parseInt를 사용하십시오. 항상 형변환을 위한 기수(radix)를 인수로 전달하십시오.

    varinputValue='4';// badvarval=newNumber(inputValue);// badvarval=+inputValue;// badvarval=inputValue>>0;// badvarval=parseInt(inputValue);// goodvarval=Number(inputValue);// goodvarval=parseInt(inputValue,10);
  • 어떤 이유에 의해 parseInt 가 병목이 되고, 성능적인 이유로 Bitshift를 사용할 필요가 있을 경우, 하려고 하는것에 대해, why(왜)와 what(무엇)의 설명을 코멘트로 남겨주십시오.

    // good/** * parseInt가 병목을 일으키므로 * Bitshift로 문자열을 수치로 강제적으로 변환하는 방법으로 * 성능을 개선시킵니다. */varval=inputValue>>0;
  • Booleans:

    varage=0;// badvarhasAge=newBoolean(age);// goodvarhasAge=Boolean(age);// goodvarhasAge=!!age;

    [↑]

  • 한문자 이름은 피하십시오. 이름에서 의도를 읽을 수 있도록 하십시오.

    // badfunctionq(){// ...stuff...}// goodfunctionquery(){// ..stuff..}
  • Object, 함수, 그리고 인스턴스로는 camelCase를 사용하십시오.

    // badvarOBJEcttsssss={};varthis_is_my_object={};varthis-is-my-object={};functionc(){};varu=newuser({name: 'Bob Parr'});// goodvarthisIsMyObject={};functionthisIsMyFunction(){};varuser=newUser({name: 'Bob Parr'});
  • Class와 생성자에는 PascalCase를 사용하십시오.

    // badfunctionuser(options){this.name=options.name;}varbad=newuser({name: 'nope'});// goodfunctionUser(options){this.name=options.name;}vargood=newUser({name: 'yup'});
  • private 속성 이름은 밑줄 _ 을 사용하십시오.

    // badthis.__firstName__='Panda';this.firstName_='Panda';// goodthis._firstName='Panda';
  • this의 참조를 저장할 때 _this 를 사용하십시오.

    // badfunction(){varself=this;returnfunction(){console.log(self);};}// badfunction(){varthat=this;returnfunction(){console.log(that);};}// goodfunction(){var_this=this;returnfunction(){console.log(_this);};}
  • 함수에 이름을 붙여주십시오. 이것은 stack traces를 추적하기 쉽게하기 때문입니다.

    // badvarlog=function(msg){console.log(msg);};// goodvarlog=functionlog(msg){console.log(msg);};

    [↑]

  • 속성을 위한 접근자(Accessor) 함수는 필요 없습니다.

  • 접근자 함수가 필요한 경우 getVal() 이나 setVal('hello') 라고 사용합니다.

    // baddragon.age();// gooddragon.getAge();// baddragon.age(25);// gooddragon.setAge(25);
  • 속성이 boolean의 경우 isVal() 이나 hasVal() 라고 사용합니다.

    // badif(!dragon.age()){returnfalse;}// goodif(!dragon.hasAge()){returnfalse;}
  • 일관된다면 get() 이나 set() 이라는 함수를 작성해도 좋습니다.

    functionJedi(options){options||(options={});varlightsaber=options.lightsaber||'blue';this.set('lightsaber',lightsaber);}Jedi.prototype.set=function(key,val){this[key]=val;};Jedi.prototype.get=function(key){returnthis[key];};

    [↑]

  • 새 Object에서 프로토타입을 재정의하는 것이 아니라, 프로토타입 객체에 메서드를 추가해 주십시오. 프로토타입을 재정의하면 상속이 불가능합니다. 프로토타입을 리셋하는것으로 베이스 클래스를 재정의 할 수 있습니다.

    functionJedi(){console.log('new jedi');}// badJedi.prototype={fight: functionfight(){console.log('fighting');},block: functionblock(){console.log('blocking');}};// goodJedi.prototype.fight=functionfight(){console.log('fighting');};Jedi.prototype.block=functionblock(){console.log('blocking');};
  • 메소드의 반환 값으로 this를 반환함으로써 메소드 체인을 할 수 있습니다.

    // badJedi.prototype.jump=function(){this.jumping=true;returntrue;};Jedi.prototype.setHeight=function(height){this.height=height;};varluke=newJedi();luke.jump();// => trueluke.setHeight(20)// => undefined// goodJedi.prototype.jump=function(){this.jumping=true;returnthis;};Jedi.prototype.setHeight=function(height){this.height=height;returnthis;};varluke=newJedi();luke.jump().setHeight(20);
  • 독자적인 toString()을 만들 수도 있지만 올바르게 작동하는지, 부작용이 없는 것만은 확인해 주십시오.

    functionJedi(options){options||(options={});this.name=options.name||'no name';}Jedi.prototype.getName=functiongetName(){returnthis.name;};Jedi.prototype.toString=functiontoString(){return'Jedi - '+this.getName();};

    [↑]

  • (DOM 이벤트나 Backbone events와 같은 고유의) 이벤트 탑재체(payloads)의 값을 전달하는 경우 원시 값(raw value) 대신 해시 인수(hash)를 전달합니다. 이렇게하는 것으로 나중에 개발자가 이벤트와 관련된 모든 핸들러를 찾아 업데이트 하지 않고 이벤트 탑재체(payloads)에 값을 추가 할 수 있습니다. 예를 들어, 이것 대신 :

    // bad$(this).trigger('listingUpdated',listing.id);
    ...
    $(this).on('listingUpdated',function(e,listingId){// do something with listingId});

    이쪽을 선호합니다.:

    // good$(this).trigger('listingUpdated',{listingId : listing.id});
    ...
    $(this).on('listingUpdated',function(e,data){// do something with data.listingId});

[↑]

  • 모듈의 시작은 ! 로 시작하십시오. 이것은 문말에 세미콜론을 넣는것을 잊은 모듈을 연결할때 런타임 오류가 발생하지 않기 때문입니다.

  • 파일 이름은 camelCase를 사용하여 같은 이름의 폴더에 저장해주십시오. 또한 단독으로 공개할 경우 이름을 일치시켜주십시오.

  • noConflict() 라는 명칭으로 (이름이 겹쳐 덮어 써지기 전의) 모듈을 반환하는 메서드를 추가해주십시오.

  • 항상 모듈의 시작 부분에서 'use strict';를 선언해주십시오.

    // fancyInput/fancyInput.js!function(global){'use strict';varpreviousFancyInput=global.FancyInput;functionFancyInput(options){this.options=options||{};}FancyInput.noConflict=functionnoConflict(){global.FancyInput=previousFancyInput;returnFancyInput;};global.FancyInput=FancyInput;}(this);

    [↑]

  • jQuery Object의 변수 앞에는 $을 부여해 주십시오.

    // badvarsidebar=$('.sidebar');// goodvar$sidebar=$('.sidebar');
  • jQuery 쿼리결과를 캐시해주십시오.

    // badfunctionsetSidebar(){$('.sidebar').hide();// ...stuff...$('.sidebar').css({'background-color': 'pink'});}// goodfunctionsetSidebar(){var$sidebar=$('.sidebar');$sidebar.hide();// ...stuff...$sidebar.css({'background-color': 'pink'});}
  • DOM 검색은 Cascading $('.sidebar ul') 이나 parent > child $('.sidebar > ul') 를 사용해주십시오. jsPerf

  • jQuery Object 검색은 스코프가 붙은 find를 사용해주십시오.

    // bad$('ul','.sidebar').hide();// bad$('.sidebar').find('ul').hide();// good$('.sidebar ul').hide();// good$('.sidebar > ul').hide();// good$sidebar.find('ul');

    [↑]

[↑]

  • 네!(Yup.)

    function(){returntrue;}

    [↑]

[↑]

Read This

Other Styleguides

Other Styles

Further Reading

Books

Blogs

[↑]

This is a list of organizations that are using this style guide. Send us a pull request or open an issue and we'll add you to the list.

This style guide is also available in other languages:

(The MIT License)

Copyright (c) 2012 Airbnb

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

[↑]

};

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' javascript-style-guide/es5.md at master · tipjs/javascript-style-guide · GitHub
Skip to content

Latest commit

History

History
1524 lines (1122 loc) · 39.4 KB

File metadata and controls

1524 lines (1122 loc) · 39.4 KB

원문:https://github.com/airbnb/javascript

Airbnb JavaScript 스타일 가이드() {

  1. Types
  2. Objects
  3. Arrays
  4. Strings
  5. Functions
  6. Properties
  7. Variables
  8. Hoisting
  9. Conditional Expressions & Equality
  10. Blocks
  11. Comments
  12. Whitespace
  13. Commas
  14. Semicolons
  15. Type Casting & Coercion
  16. Naming Conventions
  17. Accessors
  18. Constructors
  19. Events
  20. Modules
  21. jQuery
  22. ES5 Compatibility
  23. Testing
  24. Performance
  25. Resources
  26. In the Wild
  27. Translation
  28. The JavaScript Style Guide Guide
  29. Contributors
  30. License
  • Primitives: primitive type은 그 값을 직접 조작합니다.

    • string
    • number
    • boolean
    • null
    • undefined
    varfoo=1,bar=foo;bar=9;console.log(foo,bar);// => 1, 9
  • Complex: 참조형(Complex)은 참조를 통해 값을 조작합니다.

    • object
    • array
    • function
    varfoo=[1,2],bar=foo;bar[0]=9;console.log(foo[0],bar[0]);// => 9, 9

    [↑]

  • Object를 만들 때는 리터럴 구문을 사용하십시오.

    // badvaritem=newObject();// goodvaritem={};
  • 예약어(reserved words)를 키로 사용하지 마십시오. 이것은 IE8에서 동작하지 않습니다. More info

    // badvarsuperman={default: {clark: 'kent'},private: true};// goodvarsuperman={defaults: {clark: 'kent'},hidden: true};
  • 예약어 대신 알기 쉬운 동의어(readable synonyms)를 사용하십시오.

    // badvarsuperman={class: 'alien'};// badvarsuperman={klass: 'alien'};// goodvarsuperman={type: 'alien'};

    [↑]

  • 배열을 만들 때 리터럴 구문을 사용하십시오.

    // badvaritems=newArray();// goodvaritems=[];
  • 길이를 알 수없는 경우는 Array#push를 사용하십시오.

    varsomeStack=[];// badsomeStack[someStack.length]='abracadabra';// goodsomeStack.push('abracadabra');
  • 배열을 복사 할 필요가있는 경우 Array#slice를 사용하십시오. jsPerf

    varlen=items.length,itemsCopy=[],i;// badfor(i=0;i<len;i++){itemsCopy[i]=items[i];}// gooditemsCopy=items.slice();
  • Array와 비슷한(Array-Like)한 Object를 Array에 변환하는 경우는 Array#slice를 사용하십시오.

    functiontrigger(){varargs=Array.prototype.slice.call(arguments);
    ...
    }

[↑]

  • 문자열은 작은 따옴표''를 사용하십시오.

    // badvarname="Bob Parr";// goodvarname='Bob Parr';// badvarfullName="Bob "+this.lastName;// goodvarfullName='Bob '+this.lastName;
  • 80 문자 이상의 문자열은 문자열 연결을 사용하여 여러 줄에 걸쳐 기술 할 필요가 있습니다.

  • Note : 문자열 연결을 많이하면 성능에 영향을 줄 수 있습니다. jsPerf & Discussion

    // badvarerrorMessage='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.';// badvarerrorMessage='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.';// goodvarerrorMessage='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.';
  • 프로그램에서 문자열을 생성 할 필요가 있는 경우 (특히 IE는) 문자열 연결 대신 Array#join을 사용하십시오. 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;// badfunctioninbox(messages){items='<ul>';for(i=0;i<length;i++){items+='<li>'+messages[i].message+'</li>';}returnitems+'</ul>';}// goodfunctioninbox(messages){items=[];for(i=0;i<length;i++){items[i]=messages[i].message;}return'<ul><li>'+items.join('</li><li>')+'</li></ul>';}

    [↑]

  • 함수식(Function expressions)

    // 익명함수식(anonymous function expression)varanonymous=function(){returntrue;};// 명명된 함수식(named function expression)varnamed=functionnamed(){returntrue;};// 즉시실행 함수식(immediately-invoked function expression (IIFE))(function(){console.log('Welcome to the Internet. Please follow me.');})();
  • (if 및 while 등) 블록 내에서 변수에 함수를 할당하는 대신 함수를 선언하지 마십시오. 브라우저는 허용하지만 (마치 'bad news bears'처럼) 모두 다른 방식으로 해석됩니다.

  • Note: ECMA-262에서는block은 statements의 목록에 정의되어 있습니다 만, 함수 선언은 statements가 없습니다. 이 문제는 ECMA-262의 설명을 참조하십시오. .

    // badif(currentUser){functiontest(){console.log('Nope.');}}// goodvartest;if(currentUser){test=functiontest(){console.log('Yup.');};}
  • 매개 변수(parameter)에 arguments를 절대 지정하지 마십시오. 이것은 함수 범위로 전달 될arguments객체의 참조를 덮어 쓸 것입니다.

    // badfunctionnope(name,options,arguments){// ...stuff...}// goodfunctionyup(name,options,args){// ...stuff...}

    [↑]

  • 속성에 액세스하려면 도트.를 사용하십시오.

    varluke={jedi: true,age: 28};// badvarisJedi=luke['jedi'];// goodvarisJedi=luke.jedi;
  • 변수를 사용하여 속성에 접근하려면 대괄호[]을 사용하십시오.

    varluke={jedi: true,age: 28};functiongetProp(prop){returnluke[prop];}varisJedi=getProp('jedi');

    [↑]

  • 변수를 선언 할 때는 항상 var를 사용하십시오. 그렇지 않으면 전역 변수로 선언됩니다. 전역 네임 스페이스를 오염시키지 않도록 Captain Planet도 경고하고 있습니다.

    // badsuperPower=newSuperPower();// goodvarsuperPower=newSuperPower();
  • 여러 변수를 선언하려면 하나의 var를 사용하여 변수마다 줄바꿈하여 선언하십시오.

    // badvaritems=getItems();vargoSportsTeam=true;vardragonball='z';// goodvaritems=getItems(),goSportsTeam=true,dragonball='z';
  • 정의되지 않은 변수를 마지막으로 선언하십시오. 이것은 나중에 이미 할당된 변수 중 하나를 지정해야하는 경우에 유용합니다.

    // badvari,len,dragonball,items=getItems(),goSportsTeam=true;// badvari,items=getItems(),dragonball,goSportsTeam=true,len;// goodvaritems=getItems(),goSportsTeam=true,dragonball,length,i;
  • 변수의 할당은 스코프의 시작 부분에서 해주십시오. 이것은 변수 선언과 Hoisting 관련 문제를 해결합니다.

    // badfunction(){test();console.log('doing stuff..');//..other stuff..varname=getName();if(name==='test'){returnfalse;}returnname;}// goodfunction(){varname=getName();test();console.log('doing stuff..');//..other stuff..if(name==='test'){returnfalse;}returnname;}// badfunction(){varname=getName();if(!arguments.length){returnfalse;}returntrue;}// goodfunction(){if(!arguments.length){returnfalse;}varname=getName();returntrue;}

    [↑]

  • 해당 스코프의 시작 부분에 Hoist된 변수선언은 할당되지 않습니다.

    // (notDefined가 전역 변수에 존재하지 않는다고 가정했을 경우)// 이것은 동작하지 않습니다.functionexample(){console.log(notDefined);// => throws a ReferenceError}// 그 변수를 참조하는 코드 후에 그 변수를 선언 한 경우// 변수가 Hoist된 상태에서 작동합니다.// Note : `true`라는 값 자체는 Hoist되지 않습니다.functionexample(){console.log(declaredButNotAssigned);// => undefinedvardeclaredButNotAssigned=true;}// 인터 프린터는 변수 선언을 스코프의 시작 부분에 Hoist합니다.// 위의 예는 다음과 같이 다시 작성할 수 있습니다.functionexample(){vardeclaredButNotAssigned;console.log(declaredButNotAssigned);// => undefineddeclaredButNotAssigned=true;}
  • 익명 함수의 경우 함수가 할당되기 전에 변수가 Hoist될 수 있습니다.

    functionexample(){console.log(anonymous);// => undefinedanonymous();// => TypeError anonymous is not a functionvaranonymous=function(){console.log('anonymous function expression');};}
  • 명명 된 함수의 경우도 마찬가지로 변수가 Hoist될 수 있습니다. 함수 이름과 함수 본체는 Hoist되지 않습니다.

    functionexample(){console.log(named);// => undefinednamed();// => TypeError named is not a functionsuperPower();// => ReferenceError superPower is not definedvarnamed=functionsuperPower(){console.log('Flying');};}// 함수이름과 변수이름이 같은 경우에도 같은 일이 일어납니다.functionexample(){console.log(named);// => undefinednamed();// => TypeError named is not a functionvarnamed=functionnamed(){console.log('named');}}
  • 함수 선언은 함수이름과 함수본문이 Hoist됩니다.

    functionexample(){superPower();// => FlyingfunctionsuperPower(){console.log('Flying');}}
  • 더 자세한 정보는 Ben CherryJavaScript Scoping & Hoisting를 참조하십시오.

    [↑]

  • ==!= 보다는 ===!== 를 사용해 주십시오

  • 조건식은ToBoolean 메소드에 의해 엄밀하게 비교됩니다. 항상 이 간단한 규칙에 따라 주십시오.

    • Objectstrue 로 평가됩니다.
    • undefinedfalse 로 평가됩니다.
    • nullfalse 로 평가됩니다.
    • Booleansboolean형의 값 으로 평가됩니다.
    • Numberstrue 로 평가됩니다. 하지만 +0, -0, or NaN 의 경우는 false 입니다.
    • Stringstrue 로 평가됩니다. 하지만 빈문자 '' 의 경우는 false 입니다.
    if([0]){// true// Array는 Object 이므로 true 로 평가됩니다.}
  • 짧은형식을 사용하십시오.

    // badif(name!==''){// ...stuff...}// goodif(name){// ...stuff...}// badif(collection.length>0){// ...stuff...}// goodif(collection.length){// ...stuff...}
  • 더 자세한 정보는 Angus Croll 의 Truth Equality and JavaScript를 참고해 주십시오.

    [↑]

  • 복수행 블록은 중괄호 ({})를 사용하십시오.

    // badif(test)returnfalse;// goodif(test)returnfalse;// goodif(test){returnfalse;}// badfunction(){returnfalse;}// goodfunction(){returnfalse;}

    [↑]

  • 복수행의 코멘트는 /** ... */ 를 사용해 주십시오. 그 안에는 설명과 모든 매개 변수와 반환 값에 대한 형식과 값을 설명합니다.

    // bad// make() returns a new element// based on the passed in tag name//// @param <String> tag// @return <Element> elementfunctionmake(tag){// ...stuff...returnelement;}// good/** * make() returns a new element * based on the passed in tag name * * @param <String> tag * @return <Element> element */functionmake(tag){// ...stuff...returnelement;}
  • 한 줄 주석에는//를 사용하십시오. 코멘트를 추가하고 싶은 코드의 상단에 작성하십시오. 또한 주석 앞에 빈 줄을 넣어주십시오.

    // badvaractive=true;// is current tab// good// is current tabvaractive=true;// badfunctiongetType(){console.log('fetching type...');// set the default type to 'no type'vartype=this._type||'no type';returntype;}// goodfunctiongetType(){console.log('fetching type...');// set the default type to 'no type'vartype=this._type||'no type';returntype;}
  • 문제를 지적하고 재고를 촉구하거나 문제에 대한 해결책을 제시하는 등 의견의 앞에 FIXMETODO를 붙이는 것으로 다른 개발자의 빠른 이해를 도울 수 있습니다. 이러한 어떤 액션을 동반한다는 의미에서 일반 코멘트와는 다릅니다. 액션은 FIXME - 해결책이 필요 또는 TODO - 구현이 필요 입니다.

  • 문제에 대한 코멘트로 // FIXME :를 사용하십시오.

    functionCalculator(){// FIXME: 전역 변수를 사용해서는 안됩니다.total=0;returnthis;}
  • 문제 해결책에 대한 코멘트로 // TODO :를 사용하십시오.

    functionCalculator(){// TODO: total은 옵션 매개 변수로 설정되어야 함.this.total=0;returnthis;}

[↑]

  • 탭에는 공백 2개를 설정하십시오.

    // badfunction(){∙∙∙∙varname;}// badfunction(){∙varname;}// goodfunction(){∙∙varname;}
  • 중괄호({})의 앞에 공백을 하나 넣어주십시오.

    // badfunctiontest(){console.log('test');}// goodfunctiontest(){console.log('test');}// baddog.set('attr',{age: '1 year',breed: 'Bernese Mountain Dog'});// gooddog.set('attr',{age: '1 year',breed: 'Bernese Mountain Dog'});
  • 파일의 마지막에는 빈 줄을 하나 넣어주십시오.

    // bad(function(global){// ...stuff...})(this);
    // good(function(global){// ...stuff...})(this);
  • 메소드 체인이 길어지는 경우 적절히 들여쓰기(indentation) 하십시오.

    // bad$('#items').find('.selected').highlight().end().find('.open').updateCount();// good$('#items').find('.selected').highlight().end().find('.open').updateCount();// badvarleds=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);// goodvarleds=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);

    [↑]

  • 선두의 comma는 하지마십시오.

    // badvaronce,upon,aTime;// goodvaronce,upon,aTime;// badvarhero={firstName: 'Bob',lastName: 'Parr',heroName: 'Mr. Incredible',superPower: 'strength'};// goodvarhero={firstName: 'Bob',lastName: 'Parr',heroName: 'Mr. Incredible',superPower: 'strength'};
  • 말미의 불필요한 쉼표도 하지 마십시오. 이것은 IE6/7과 quirksmode의 IE9에서 문제를 일으킬 수 있습니다. 또한 ES3의 일부 구현에서 불필요한 쉼표가 있는 경우, 배열 길이를 추가합니다. 이것은 ES5에서 분명해졌습니다.(source):

    제 5 판에서는 말미의 불필요한 쉼표가 있는 ArrayInitialiser (배열 초기화 연산자)라도 배열에 길이를 추가하지 않는다는 사실을 명확히하고 있습니다. 이것은 제 3 판에서 의미적인 변경은 아닙니다만, 일부의 구현은 이전부터 이것을 오해하고 있었을지도 모릅니다.

    // badvarhero={firstName: 'Kevin',lastName: 'Flynn',};varheroes=['Batman','Superman',];// goodvarhero={firstName: 'Kevin',lastName: 'Flynn'};varheroes=['Batman','Superman'];

    [↑]

  • 네!(Yup.)

    // bad(function(){varname='Skywalker'returnname})()// good(function(){varname='Skywalker';returnname;})();// good;(function(){varname='Skywalker';returnname;})();

    [↑]

  • 문의 시작 부분에서 형을 강제합니다.

  • Strings:

    // => this.reviewScore = 9;// badvartotalScore=this.reviewScore+'';// goodvartotalScore=''+this.reviewScore;// badvartotalScore=''+this.reviewScore+' total score';// goodvartotalScore=this.reviewScore+' total score';
  • 숫자는parseInt를 사용하십시오. 항상 형변환을 위한 기수(radix)를 인수로 전달하십시오.

    varinputValue='4';// badvarval=newNumber(inputValue);// badvarval=+inputValue;// badvarval=inputValue>>0;// badvarval=parseInt(inputValue);// goodvarval=Number(inputValue);// goodvarval=parseInt(inputValue,10);
  • 어떤 이유에 의해 parseInt 가 병목이 되고, 성능적인 이유로 Bitshift를 사용할 필요가 있을 경우, 하려고 하는것에 대해, why(왜)와 what(무엇)의 설명을 코멘트로 남겨주십시오.

    // good/** * parseInt가 병목을 일으키므로 * Bitshift로 문자열을 수치로 강제적으로 변환하는 방법으로 * 성능을 개선시킵니다. */varval=inputValue>>0;
  • Booleans:

    varage=0;// badvarhasAge=newBoolean(age);// goodvarhasAge=Boolean(age);// goodvarhasAge=!!age;

    [↑]

  • 한문자 이름은 피하십시오. 이름에서 의도를 읽을 수 있도록 하십시오.

    // badfunctionq(){// ...stuff...}// goodfunctionquery(){// ..stuff..}
  • Object, 함수, 그리고 인스턴스로는 camelCase를 사용하십시오.

    // badvarOBJEcttsssss={};varthis_is_my_object={};varthis-is-my-object={};functionc(){};varu=newuser({name: 'Bob Parr'});// goodvarthisIsMyObject={};functionthisIsMyFunction(){};varuser=newUser({name: 'Bob Parr'});
  • Class와 생성자에는 PascalCase를 사용하십시오.

    // badfunctionuser(options){this.name=options.name;}varbad=newuser({name: 'nope'});// goodfunctionUser(options){this.name=options.name;}vargood=newUser({name: 'yup'});
  • private 속성 이름은 밑줄 _ 을 사용하십시오.

    // badthis.__firstName__='Panda';this.firstName_='Panda';// goodthis._firstName='Panda';
  • this의 참조를 저장할 때 _this 를 사용하십시오.

    // badfunction(){varself=this;returnfunction(){console.log(self);};}// badfunction(){varthat=this;returnfunction(){console.log(that);};}// goodfunction(){var_this=this;returnfunction(){console.log(_this);};}
  • 함수에 이름을 붙여주십시오. 이것은 stack traces를 추적하기 쉽게하기 때문입니다.

    // badvarlog=function(msg){console.log(msg);};// goodvarlog=functionlog(msg){console.log(msg);};

    [↑]

  • 속성을 위한 접근자(Accessor) 함수는 필요 없습니다.

  • 접근자 함수가 필요한 경우 getVal() 이나 setVal('hello') 라고 사용합니다.

    // baddragon.age();// gooddragon.getAge();// baddragon.age(25);// gooddragon.setAge(25);
  • 속성이 boolean의 경우 isVal() 이나 hasVal() 라고 사용합니다.

    // badif(!dragon.age()){returnfalse;}// goodif(!dragon.hasAge()){returnfalse;}
  • 일관된다면 get() 이나 set() 이라는 함수를 작성해도 좋습니다.

    functionJedi(options){options||(options={});varlightsaber=options.lightsaber||'blue';this.set('lightsaber',lightsaber);}Jedi.prototype.set=function(key,val){this[key]=val;};Jedi.prototype.get=function(key){returnthis[key];};

    [↑]

  • 새 Object에서 프로토타입을 재정의하는 것이 아니라, 프로토타입 객체에 메서드를 추가해 주십시오. 프로토타입을 재정의하면 상속이 불가능합니다. 프로토타입을 리셋하는것으로 베이스 클래스를 재정의 할 수 있습니다.

    functionJedi(){console.log('new jedi');}// badJedi.prototype={fight: functionfight(){console.log('fighting');},block: functionblock(){console.log('blocking');}};// goodJedi.prototype.fight=functionfight(){console.log('fighting');};Jedi.prototype.block=functionblock(){console.log('blocking');};
  • 메소드의 반환 값으로 this를 반환함으로써 메소드 체인을 할 수 있습니다.

    // badJedi.prototype.jump=function(){this.jumping=true;returntrue;};Jedi.prototype.setHeight=function(height){this.height=height;};varluke=newJedi();luke.jump();// => trueluke.setHeight(20)// => undefined// goodJedi.prototype.jump=function(){this.jumping=true;returnthis;};Jedi.prototype.setHeight=function(height){this.height=height;returnthis;};varluke=newJedi();luke.jump().setHeight(20);
  • 독자적인 toString()을 만들 수도 있지만 올바르게 작동하는지, 부작용이 없는 것만은 확인해 주십시오.

    functionJedi(options){options||(options={});this.name=options.name||'no name';}Jedi.prototype.getName=functiongetName(){returnthis.name;};Jedi.prototype.toString=functiontoString(){return'Jedi - '+this.getName();};

    [↑]

  • (DOM 이벤트나 Backbone events와 같은 고유의) 이벤트 탑재체(payloads)의 값을 전달하는 경우 원시 값(raw value) 대신 해시 인수(hash)를 전달합니다. 이렇게하는 것으로 나중에 개발자가 이벤트와 관련된 모든 핸들러를 찾아 업데이트 하지 않고 이벤트 탑재체(payloads)에 값을 추가 할 수 있습니다. 예를 들어, 이것 대신 :

    // bad$(this).trigger('listingUpdated',listing.id);
    ...
    $(this).on('listingUpdated',function(e,listingId){// do something with listingId});

    이쪽을 선호합니다.:

    // good$(this).trigger('listingUpdated',{listingId : listing.id});
    ...
    $(this).on('listingUpdated',function(e,data){// do something with data.listingId});

[↑]

  • 모듈의 시작은 ! 로 시작하십시오. 이것은 문말에 세미콜론을 넣는것을 잊은 모듈을 연결할때 런타임 오류가 발생하지 않기 때문입니다.

  • 파일 이름은 camelCase를 사용하여 같은 이름의 폴더에 저장해주십시오. 또한 단독으로 공개할 경우 이름을 일치시켜주십시오.

  • noConflict() 라는 명칭으로 (이름이 겹쳐 덮어 써지기 전의) 모듈을 반환하는 메서드를 추가해주십시오.

  • 항상 모듈의 시작 부분에서 'use strict';를 선언해주십시오.

    // fancyInput/fancyInput.js!function(global){'use strict';varpreviousFancyInput=global.FancyInput;functionFancyInput(options){this.options=options||{};}FancyInput.noConflict=functionnoConflict(){global.FancyInput=previousFancyInput;returnFancyInput;};global.FancyInput=FancyInput;}(this);

    [↑]

  • jQuery Object의 변수 앞에는 $을 부여해 주십시오.

    // badvarsidebar=$('.sidebar');// goodvar$sidebar=$('.sidebar');
  • jQuery 쿼리결과를 캐시해주십시오.

    // badfunctionsetSidebar(){$('.sidebar').hide();// ...stuff...$('.sidebar').css({'background-color': 'pink'});}// goodfunctionsetSidebar(){var$sidebar=$('.sidebar');$sidebar.hide();// ...stuff...$sidebar.css({'background-color': 'pink'});}
  • DOM 검색은 Cascading $('.sidebar ul') 이나 parent > child $('.sidebar > ul') 를 사용해주십시오. jsPerf

  • jQuery Object 검색은 스코프가 붙은 find를 사용해주십시오.

    // bad$('ul','.sidebar').hide();// bad$('.sidebar').find('ul').hide();// good$('.sidebar ul').hide();// good$('.sidebar > ul').hide();// good$sidebar.find('ul');

    [↑]

[↑]

  • 네!(Yup.)

    function(){returntrue;}

    [↑]

[↑]

Read This

Other Styleguides

Other Styles

Further Reading

Books

Blogs

[↑]

This is a list of organizations that are using this style guide. Send us a pull request or open an issue and we'll add you to the list.

This style guide is also available in other languages:

(The MIT License)

Copyright (c) 2012 Airbnb

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

[↑]

};

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' javascript-style-guide/es5.md at master · tipjs/javascript-style-guide · GitHub
Skip to content

Latest commit

History

History
1524 lines (1122 loc) · 39.4 KB

File metadata and controls

1524 lines (1122 loc) · 39.4 KB

원문:https://github.com/airbnb/javascript

Airbnb JavaScript 스타일 가이드() {

  1. Types
  2. Objects
  3. Arrays
  4. Strings
  5. Functions
  6. Properties
  7. Variables
  8. Hoisting
  9. Conditional Expressions & Equality
  10. Blocks
  11. Comments
  12. Whitespace
  13. Commas
  14. Semicolons
  15. Type Casting & Coercion
  16. Naming Conventions
  17. Accessors
  18. Constructors
  19. Events
  20. Modules
  21. jQuery
  22. ES5 Compatibility
  23. Testing
  24. Performance
  25. Resources
  26. In the Wild
  27. Translation
  28. The JavaScript Style Guide Guide
  29. Contributors
  30. License
  • Primitives: primitive type은 그 값을 직접 조작합니다.

    • string
    • number
    • boolean
    • null
    • undefined
    varfoo=1,bar=foo;bar=9;console.log(foo,bar);// => 1, 9
  • Complex: 참조형(Complex)은 참조를 통해 값을 조작합니다.

    • object
    • array
    • function
    varfoo=[1,2],bar=foo;bar[0]=9;console.log(foo[0],bar[0]);// => 9, 9

    [↑]

  • Object를 만들 때는 리터럴 구문을 사용하십시오.

    // badvaritem=newObject();// goodvaritem={};
  • 예약어(reserved words)를 키로 사용하지 마십시오. 이것은 IE8에서 동작하지 않습니다. More info

    // badvarsuperman={default: {clark: 'kent'},private: true};// goodvarsuperman={defaults: {clark: 'kent'},hidden: true};
  • 예약어 대신 알기 쉬운 동의어(readable synonyms)를 사용하십시오.

    // badvarsuperman={class: 'alien'};// badvarsuperman={klass: 'alien'};// goodvarsuperman={type: 'alien'};

    [↑]

  • 배열을 만들 때 리터럴 구문을 사용하십시오.

    // badvaritems=newArray();// goodvaritems=[];
  • 길이를 알 수없는 경우는 Array#push를 사용하십시오.

    varsomeStack=[];// badsomeStack[someStack.length]='abracadabra';// goodsomeStack.push('abracadabra');
  • 배열을 복사 할 필요가있는 경우 Array#slice를 사용하십시오. jsPerf

    varlen=items.length,itemsCopy=[],i;// badfor(i=0;i<len;i++){itemsCopy[i]=items[i];}// gooditemsCopy=items.slice();
  • Array와 비슷한(Array-Like)한 Object를 Array에 변환하는 경우는 Array#slice를 사용하십시오.

    functiontrigger(){varargs=Array.prototype.slice.call(arguments);
    ...
    }

[↑]

  • 문자열은 작은 따옴표''를 사용하십시오.

    // badvarname="Bob Parr";// goodvarname='Bob Parr';// badvarfullName="Bob "+this.lastName;// goodvarfullName='Bob '+this.lastName;
  • 80 문자 이상의 문자열은 문자열 연결을 사용하여 여러 줄에 걸쳐 기술 할 필요가 있습니다.

  • Note : 문자열 연결을 많이하면 성능에 영향을 줄 수 있습니다. jsPerf & Discussion

    // badvarerrorMessage='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.';// badvarerrorMessage='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.';// goodvarerrorMessage='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.';
  • 프로그램에서 문자열을 생성 할 필요가 있는 경우 (특히 IE는) 문자열 연결 대신 Array#join을 사용하십시오. 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;// badfunctioninbox(messages){items='<ul>';for(i=0;i<length;i++){items+='<li>'+messages[i].message+'</li>';}returnitems+'</ul>';}// goodfunctioninbox(messages){items=[];for(i=0;i<length;i++){items[i]=messages[i].message;}return'<ul><li>'+items.join('</li><li>')+'</li></ul>';}

    [↑]

  • 함수식(Function expressions)

    // 익명함수식(anonymous function expression)varanonymous=function(){returntrue;};// 명명된 함수식(named function expression)varnamed=functionnamed(){returntrue;};// 즉시실행 함수식(immediately-invoked function expression (IIFE))(function(){console.log('Welcome to the Internet. Please follow me.');})();
  • (if 및 while 등) 블록 내에서 변수에 함수를 할당하는 대신 함수를 선언하지 마십시오. 브라우저는 허용하지만 (마치 'bad news bears'처럼) 모두 다른 방식으로 해석됩니다.

  • Note: ECMA-262에서는block은 statements의 목록에 정의되어 있습니다 만, 함수 선언은 statements가 없습니다. 이 문제는 ECMA-262의 설명을 참조하십시오. .

    // badif(currentUser){functiontest(){console.log('Nope.');}}// goodvartest;if(currentUser){test=functiontest(){console.log('Yup.');};}
  • 매개 변수(parameter)에 arguments를 절대 지정하지 마십시오. 이것은 함수 범위로 전달 될arguments객체의 참조를 덮어 쓸 것입니다.

    // badfunctionnope(name,options,arguments){// ...stuff...}// goodfunctionyup(name,options,args){// ...stuff...}

    [↑]

  • 속성에 액세스하려면 도트.를 사용하십시오.

    varluke={jedi: true,age: 28};// badvarisJedi=luke['jedi'];// goodvarisJedi=luke.jedi;
  • 변수를 사용하여 속성에 접근하려면 대괄호[]을 사용하십시오.

    varluke={jedi: true,age: 28};functiongetProp(prop){returnluke[prop];}varisJedi=getProp('jedi');

    [↑]

  • 변수를 선언 할 때는 항상 var를 사용하십시오. 그렇지 않으면 전역 변수로 선언됩니다. 전역 네임 스페이스를 오염시키지 않도록 Captain Planet도 경고하고 있습니다.

    // badsuperPower=newSuperPower();// goodvarsuperPower=newSuperPower();
  • 여러 변수를 선언하려면 하나의 var를 사용하여 변수마다 줄바꿈하여 선언하십시오.

    // badvaritems=getItems();vargoSportsTeam=true;vardragonball='z';// goodvaritems=getItems(),goSportsTeam=true,dragonball='z';
  • 정의되지 않은 변수를 마지막으로 선언하십시오. 이것은 나중에 이미 할당된 변수 중 하나를 지정해야하는 경우에 유용합니다.

    // badvari,len,dragonball,items=getItems(),goSportsTeam=true;// badvari,items=getItems(),dragonball,goSportsTeam=true,len;// goodvaritems=getItems(),goSportsTeam=true,dragonball,length,i;
  • 변수의 할당은 스코프의 시작 부분에서 해주십시오. 이것은 변수 선언과 Hoisting 관련 문제를 해결합니다.

    // badfunction(){test();console.log('doing stuff..');//..other stuff..varname=getName();if(name==='test'){returnfalse;}returnname;}// goodfunction(){varname=getName();test();console.log('doing stuff..');//..other stuff..if(name==='test'){returnfalse;}returnname;}// badfunction(){varname=getName();if(!arguments.length){returnfalse;}returntrue;}// goodfunction(){if(!arguments.length){returnfalse;}varname=getName();returntrue;}

    [↑]

  • 해당 스코프의 시작 부분에 Hoist된 변수선언은 할당되지 않습니다.

    // (notDefined가 전역 변수에 존재하지 않는다고 가정했을 경우)// 이것은 동작하지 않습니다.functionexample(){console.log(notDefined);// => throws a ReferenceError}// 그 변수를 참조하는 코드 후에 그 변수를 선언 한 경우// 변수가 Hoist된 상태에서 작동합니다.// Note : `true`라는 값 자체는 Hoist되지 않습니다.functionexample(){console.log(declaredButNotAssigned);// => undefinedvardeclaredButNotAssigned=true;}// 인터 프린터는 변수 선언을 스코프의 시작 부분에 Hoist합니다.// 위의 예는 다음과 같이 다시 작성할 수 있습니다.functionexample(){vardeclaredButNotAssigned;console.log(declaredButNotAssigned);// => undefineddeclaredButNotAssigned=true;}
  • 익명 함수의 경우 함수가 할당되기 전에 변수가 Hoist될 수 있습니다.

    functionexample(){console.log(anonymous);// => undefinedanonymous();// => TypeError anonymous is not a functionvaranonymous=function(){console.log('anonymous function expression');};}
  • 명명 된 함수의 경우도 마찬가지로 변수가 Hoist될 수 있습니다. 함수 이름과 함수 본체는 Hoist되지 않습니다.

    functionexample(){console.log(named);// => undefinednamed();// => TypeError named is not a functionsuperPower();// => ReferenceError superPower is not definedvarnamed=functionsuperPower(){console.log('Flying');};}// 함수이름과 변수이름이 같은 경우에도 같은 일이 일어납니다.functionexample(){console.log(named);// => undefinednamed();// => TypeError named is not a functionvarnamed=functionnamed(){console.log('named');}}
  • 함수 선언은 함수이름과 함수본문이 Hoist됩니다.

    functionexample(){superPower();// => FlyingfunctionsuperPower(){console.log('Flying');}}
  • 더 자세한 정보는 Ben CherryJavaScript Scoping & Hoisting를 참조하십시오.

    [↑]

  • ==!= 보다는 ===!== 를 사용해 주십시오

  • 조건식은ToBoolean 메소드에 의해 엄밀하게 비교됩니다. 항상 이 간단한 규칙에 따라 주십시오.

    • Objectstrue 로 평가됩니다.
    • undefinedfalse 로 평가됩니다.
    • nullfalse 로 평가됩니다.
    • Booleansboolean형의 값 으로 평가됩니다.
    • Numberstrue 로 평가됩니다. 하지만 +0, -0, or NaN 의 경우는 false 입니다.
    • Stringstrue 로 평가됩니다. 하지만 빈문자 '' 의 경우는 false 입니다.
    if([0]){// true// Array는 Object 이므로 true 로 평가됩니다.}
  • 짧은형식을 사용하십시오.

    // badif(name!==''){// ...stuff...}// goodif(name){// ...stuff...}// badif(collection.length>0){// ...stuff...}// goodif(collection.length){// ...stuff...}
  • 더 자세한 정보는 Angus Croll 의 Truth Equality and JavaScript를 참고해 주십시오.

    [↑]

  • 복수행 블록은 중괄호 ({})를 사용하십시오.

    // badif(test)returnfalse;// goodif(test)returnfalse;// goodif(test){returnfalse;}// badfunction(){returnfalse;}// goodfunction(){returnfalse;}

    [↑]

  • 복수행의 코멘트는 /** ... */ 를 사용해 주십시오. 그 안에는 설명과 모든 매개 변수와 반환 값에 대한 형식과 값을 설명합니다.

    // bad// make() returns a new element// based on the passed in tag name//// @param <String> tag// @return <Element> elementfunctionmake(tag){// ...stuff...returnelement;}// good/** * make() returns a new element * based on the passed in tag name * * @param <String> tag * @return <Element> element */functionmake(tag){// ...stuff...returnelement;}
  • 한 줄 주석에는//를 사용하십시오. 코멘트를 추가하고 싶은 코드의 상단에 작성하십시오. 또한 주석 앞에 빈 줄을 넣어주십시오.

    // badvaractive=true;// is current tab// good// is current tabvaractive=true;// badfunctiongetType(){console.log('fetching type...');// set the default type to 'no type'vartype=this._type||'no type';returntype;}// goodfunctiongetType(){console.log('fetching type...');// set the default type to 'no type'vartype=this._type||'no type';returntype;}
  • 문제를 지적하고 재고를 촉구하거나 문제에 대한 해결책을 제시하는 등 의견의 앞에 FIXMETODO를 붙이는 것으로 다른 개발자의 빠른 이해를 도울 수 있습니다. 이러한 어떤 액션을 동반한다는 의미에서 일반 코멘트와는 다릅니다. 액션은 FIXME - 해결책이 필요 또는 TODO - 구현이 필요 입니다.

  • 문제에 대한 코멘트로 // FIXME :를 사용하십시오.

    functionCalculator(){// FIXME: 전역 변수를 사용해서는 안됩니다.total=0;returnthis;}
  • 문제 해결책에 대한 코멘트로 // TODO :를 사용하십시오.

    functionCalculator(){// TODO: total은 옵션 매개 변수로 설정되어야 함.this.total=0;returnthis;}

[↑]

  • 탭에는 공백 2개를 설정하십시오.

    // badfunction(){∙∙∙∙varname;}// badfunction(){∙varname;}// goodfunction(){∙∙varname;}
  • 중괄호({})의 앞에 공백을 하나 넣어주십시오.

    // badfunctiontest(){console.log('test');}// goodfunctiontest(){console.log('test');}// baddog.set('attr',{age: '1 year',breed: 'Bernese Mountain Dog'});// gooddog.set('attr',{age: '1 year',breed: 'Bernese Mountain Dog'});
  • 파일의 마지막에는 빈 줄을 하나 넣어주십시오.

    // bad(function(global){// ...stuff...})(this);
    // good(function(global){// ...stuff...})(this);
  • 메소드 체인이 길어지는 경우 적절히 들여쓰기(indentation) 하십시오.

    // bad$('#items').find('.selected').highlight().end().find('.open').updateCount();// good$('#items').find('.selected').highlight().end().find('.open').updateCount();// badvarleds=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);// goodvarleds=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);

    [↑]

  • 선두의 comma는 하지마십시오.

    // badvaronce,upon,aTime;// goodvaronce,upon,aTime;// badvarhero={firstName: 'Bob',lastName: 'Parr',heroName: 'Mr. Incredible',superPower: 'strength'};// goodvarhero={firstName: 'Bob',lastName: 'Parr',heroName: 'Mr. Incredible',superPower: 'strength'};
  • 말미의 불필요한 쉼표도 하지 마십시오. 이것은 IE6/7과 quirksmode의 IE9에서 문제를 일으킬 수 있습니다. 또한 ES3의 일부 구현에서 불필요한 쉼표가 있는 경우, 배열 길이를 추가합니다. 이것은 ES5에서 분명해졌습니다.(source):

    제 5 판에서는 말미의 불필요한 쉼표가 있는 ArrayInitialiser (배열 초기화 연산자)라도 배열에 길이를 추가하지 않는다는 사실을 명확히하고 있습니다. 이것은 제 3 판에서 의미적인 변경은 아닙니다만, 일부의 구현은 이전부터 이것을 오해하고 있었을지도 모릅니다.

    // badvarhero={firstName: 'Kevin',lastName: 'Flynn',};varheroes=['Batman','Superman',];// goodvarhero={firstName: 'Kevin',lastName: 'Flynn'};varheroes=['Batman','Superman'];

    [↑]

  • 네!(Yup.)

    // bad(function(){varname='Skywalker'returnname})()// good(function(){varname='Skywalker';returnname;})();// good;(function(){varname='Skywalker';returnname;})();

    [↑]

  • 문의 시작 부분에서 형을 강제합니다.

  • Strings:

    // => this.reviewScore = 9;// badvartotalScore=this.reviewScore+'';// goodvartotalScore=''+this.reviewScore;// badvartotalScore=''+this.reviewScore+' total score';// goodvartotalScore=this.reviewScore+' total score';
  • 숫자는parseInt를 사용하십시오. 항상 형변환을 위한 기수(radix)를 인수로 전달하십시오.

    varinputValue='4';// badvarval=newNumber(inputValue);// badvarval=+inputValue;// badvarval=inputValue>>0;// badvarval=parseInt(inputValue);// goodvarval=Number(inputValue);// goodvarval=parseInt(inputValue,10);
  • 어떤 이유에 의해 parseInt 가 병목이 되고, 성능적인 이유로 Bitshift를 사용할 필요가 있을 경우, 하려고 하는것에 대해, why(왜)와 what(무엇)의 설명을 코멘트로 남겨주십시오.

    // good/** * parseInt가 병목을 일으키므로 * Bitshift로 문자열을 수치로 강제적으로 변환하는 방법으로 * 성능을 개선시킵니다. */varval=inputValue>>0;
  • Booleans:

    varage=0;// badvarhasAge=newBoolean(age);// goodvarhasAge=Boolean(age);// goodvarhasAge=!!age;

    [↑]

  • 한문자 이름은 피하십시오. 이름에서 의도를 읽을 수 있도록 하십시오.

    // badfunctionq(){// ...stuff...}// goodfunctionquery(){// ..stuff..}
  • Object, 함수, 그리고 인스턴스로는 camelCase를 사용하십시오.

    // badvarOBJEcttsssss={};varthis_is_my_object={};varthis-is-my-object={};functionc(){};varu=newuser({name: 'Bob Parr'});// goodvarthisIsMyObject={};functionthisIsMyFunction(){};varuser=newUser({name: 'Bob Parr'});
  • Class와 생성자에는 PascalCase를 사용하십시오.

    // badfunctionuser(options){this.name=options.name;}varbad=newuser({name: 'nope'});// goodfunctionUser(options){this.name=options.name;}vargood=newUser({name: 'yup'});
  • private 속성 이름은 밑줄 _ 을 사용하십시오.

    // badthis.__firstName__='Panda';this.firstName_='Panda';// goodthis._firstName='Panda';
  • this의 참조를 저장할 때 _this 를 사용하십시오.

    // badfunction(){varself=this;returnfunction(){console.log(self);};}// badfunction(){varthat=this;returnfunction(){console.log(that);};}// goodfunction(){var_this=this;returnfunction(){console.log(_this);};}
  • 함수에 이름을 붙여주십시오. 이것은 stack traces를 추적하기 쉽게하기 때문입니다.

    // badvarlog=function(msg){console.log(msg);};// goodvarlog=functionlog(msg){console.log(msg);};

    [↑]

  • 속성을 위한 접근자(Accessor) 함수는 필요 없습니다.

  • 접근자 함수가 필요한 경우 getVal() 이나 setVal('hello') 라고 사용합니다.

    // baddragon.age();// gooddragon.getAge();// baddragon.age(25);// gooddragon.setAge(25);
  • 속성이 boolean의 경우 isVal() 이나 hasVal() 라고 사용합니다.

    // badif(!dragon.age()){returnfalse;}// goodif(!dragon.hasAge()){returnfalse;}
  • 일관된다면 get() 이나 set() 이라는 함수를 작성해도 좋습니다.

    functionJedi(options){options||(options={});varlightsaber=options.lightsaber||'blue';this.set('lightsaber',lightsaber);}Jedi.prototype.set=function(key,val){this[key]=val;};Jedi.prototype.get=function(key){returnthis[key];};

    [↑]

  • 새 Object에서 프로토타입을 재정의하는 것이 아니라, 프로토타입 객체에 메서드를 추가해 주십시오. 프로토타입을 재정의하면 상속이 불가능합니다. 프로토타입을 리셋하는것으로 베이스 클래스를 재정의 할 수 있습니다.

    functionJedi(){console.log('new jedi');}// badJedi.prototype={fight: functionfight(){console.log('fighting');},block: functionblock(){console.log('blocking');}};// goodJedi.prototype.fight=functionfight(){console.log('fighting');};Jedi.prototype.block=functionblock(){console.log('blocking');};
  • 메소드의 반환 값으로 this를 반환함으로써 메소드 체인을 할 수 있습니다.

    // badJedi.prototype.jump=function(){this.jumping=true;returntrue;};Jedi.prototype.setHeight=function(height){this.height=height;};varluke=newJedi();luke.jump();// => trueluke.setHeight(20)// => undefined// goodJedi.prototype.jump=function(){this.jumping=true;returnthis;};Jedi.prototype.setHeight=function(height){this.height=height;returnthis;};varluke=newJedi();luke.jump().setHeight(20);
  • 독자적인 toString()을 만들 수도 있지만 올바르게 작동하는지, 부작용이 없는 것만은 확인해 주십시오.

    functionJedi(options){options||(options={});this.name=options.name||'no name';}Jedi.prototype.getName=functiongetName(){returnthis.name;};Jedi.prototype.toString=functiontoString(){return'Jedi - '+this.getName();};

    [↑]

  • (DOM 이벤트나 Backbone events와 같은 고유의) 이벤트 탑재체(payloads)의 값을 전달하는 경우 원시 값(raw value) 대신 해시 인수(hash)를 전달합니다. 이렇게하는 것으로 나중에 개발자가 이벤트와 관련된 모든 핸들러를 찾아 업데이트 하지 않고 이벤트 탑재체(payloads)에 값을 추가 할 수 있습니다. 예를 들어, 이것 대신 :

    // bad$(this).trigger('listingUpdated',listing.id);
    ...
    $(this).on('listingUpdated',function(e,listingId){// do something with listingId});

    이쪽을 선호합니다.:

    // good$(this).trigger('listingUpdated',{listingId : listing.id});
    ...
    $(this).on('listingUpdated',function(e,data){// do something with data.listingId});

[↑]

  • 모듈의 시작은 ! 로 시작하십시오. 이것은 문말에 세미콜론을 넣는것을 잊은 모듈을 연결할때 런타임 오류가 발생하지 않기 때문입니다.

  • 파일 이름은 camelCase를 사용하여 같은 이름의 폴더에 저장해주십시오. 또한 단독으로 공개할 경우 이름을 일치시켜주십시오.

  • noConflict() 라는 명칭으로 (이름이 겹쳐 덮어 써지기 전의) 모듈을 반환하는 메서드를 추가해주십시오.

  • 항상 모듈의 시작 부분에서 'use strict';를 선언해주십시오.

    // fancyInput/fancyInput.js!function(global){'use strict';varpreviousFancyInput=global.FancyInput;functionFancyInput(options){this.options=options||{};}FancyInput.noConflict=functionnoConflict(){global.FancyInput=previousFancyInput;returnFancyInput;};global.FancyInput=FancyInput;}(this);

    [↑]

  • jQuery Object의 변수 앞에는 $을 부여해 주십시오.

    // badvarsidebar=$('.sidebar');// goodvar$sidebar=$('.sidebar');
  • jQuery 쿼리결과를 캐시해주십시오.

    // badfunctionsetSidebar(){$('.sidebar').hide();// ...stuff...$('.sidebar').css({'background-color': 'pink'});}// goodfunctionsetSidebar(){var$sidebar=$('.sidebar');$sidebar.hide();// ...stuff...$sidebar.css({'background-color': 'pink'});}
  • DOM 검색은 Cascading $('.sidebar ul') 이나 parent > child $('.sidebar > ul') 를 사용해주십시오. jsPerf

  • jQuery Object 검색은 스코프가 붙은 find를 사용해주십시오.

    // bad$('ul','.sidebar').hide();// bad$('.sidebar').find('ul').hide();// good$('.sidebar ul').hide();// good$('.sidebar > ul').hide();// good$sidebar.find('ul');

    [↑]

[↑]

  • 네!(Yup.)

    function(){returntrue;}

    [↑]

[↑]

Read This

Other Styleguides

Other Styles

Further Reading

Books

Blogs

[↑]

This is a list of organizations that are using this style guide. Send us a pull request or open an issue and we'll add you to the list.

This style guide is also available in other languages:

(The MIT License)

Copyright (c) 2012 Airbnb

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

[↑]

};

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' javascript-style-guide/es5.md at master · tipjs/javascript-style-guide · GitHub
Skip to content

Latest commit

History

History
1524 lines (1122 loc) · 39.4 KB

File metadata and controls

1524 lines (1122 loc) · 39.4 KB

원문:https://github.com/airbnb/javascript

Airbnb JavaScript 스타일 가이드() {

  1. Types
  2. Objects
  3. Arrays
  4. Strings
  5. Functions
  6. Properties
  7. Variables
  8. Hoisting
  9. Conditional Expressions & Equality
  10. Blocks
  11. Comments
  12. Whitespace
  13. Commas
  14. Semicolons
  15. Type Casting & Coercion
  16. Naming Conventions
  17. Accessors
  18. Constructors
  19. Events
  20. Modules
  21. jQuery
  22. ES5 Compatibility
  23. Testing
  24. Performance
  25. Resources
  26. In the Wild
  27. Translation
  28. The JavaScript Style Guide Guide
  29. Contributors
  30. License
  • Primitives: primitive type은 그 값을 직접 조작합니다.

    • string
    • number
    • boolean
    • null
    • undefined
    varfoo=1,bar=foo;bar=9;console.log(foo,bar);// => 1, 9
  • Complex: 참조형(Complex)은 참조를 통해 값을 조작합니다.

    • object
    • array
    • function
    varfoo=[1,2],bar=foo;bar[0]=9;console.log(foo[0],bar[0]);// => 9, 9

    [↑]

  • Object를 만들 때는 리터럴 구문을 사용하십시오.

    // badvaritem=newObject();// goodvaritem={};
  • 예약어(reserved words)를 키로 사용하지 마십시오. 이것은 IE8에서 동작하지 않습니다. More info

    // badvarsuperman={default: {clark: 'kent'},private: true};// goodvarsuperman={defaults: {clark: 'kent'},hidden: true};
  • 예약어 대신 알기 쉬운 동의어(readable synonyms)를 사용하십시오.

    // badvarsuperman={class: 'alien'};// badvarsuperman={klass: 'alien'};// goodvarsuperman={type: 'alien'};

    [↑]

  • 배열을 만들 때 리터럴 구문을 사용하십시오.

    // badvaritems=newArray();// goodvaritems=[];
  • 길이를 알 수없는 경우는 Array#push를 사용하십시오.

    varsomeStack=[];// badsomeStack[someStack.length]='abracadabra';// goodsomeStack.push('abracadabra');
  • 배열을 복사 할 필요가있는 경우 Array#slice를 사용하십시오. jsPerf

    varlen=items.length,itemsCopy=[],i;// badfor(i=0;i<len;i++){itemsCopy[i]=items[i];}// gooditemsCopy=items.slice();
  • Array와 비슷한(Array-Like)한 Object를 Array에 변환하는 경우는 Array#slice를 사용하십시오.

    functiontrigger(){varargs=Array.prototype.slice.call(arguments);
    ...
    }

[↑]

  • 문자열은 작은 따옴표''를 사용하십시오.

    // badvarname="Bob Parr";// goodvarname='Bob Parr';// badvarfullName="Bob "+this.lastName;// goodvarfullName='Bob '+this.lastName;
  • 80 문자 이상의 문자열은 문자열 연결을 사용하여 여러 줄에 걸쳐 기술 할 필요가 있습니다.

  • Note : 문자열 연결을 많이하면 성능에 영향을 줄 수 있습니다. jsPerf & Discussion

    // badvarerrorMessage='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.';// badvarerrorMessage='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.';// goodvarerrorMessage='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.';
  • 프로그램에서 문자열을 생성 할 필요가 있는 경우 (특히 IE는) 문자열 연결 대신 Array#join을 사용하십시오. 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;// badfunctioninbox(messages){items='<ul>';for(i=0;i<length;i++){items+='<li>'+messages[i].message+'</li>';}returnitems+'</ul>';}// goodfunctioninbox(messages){items=[];for(i=0;i<length;i++){items[i]=messages[i].message;}return'<ul><li>'+items.join('</li><li>')+'</li></ul>';}

    [↑]

  • 함수식(Function expressions)

    // 익명함수식(anonymous function expression)varanonymous=function(){returntrue;};// 명명된 함수식(named function expression)varnamed=functionnamed(){returntrue;};// 즉시실행 함수식(immediately-invoked function expression (IIFE))(function(){console.log('Welcome to the Internet. Please follow me.');})();
  • (if 및 while 등) 블록 내에서 변수에 함수를 할당하는 대신 함수를 선언하지 마십시오. 브라우저는 허용하지만 (마치 'bad news bears'처럼) 모두 다른 방식으로 해석됩니다.

  • Note: ECMA-262에서는block은 statements의 목록에 정의되어 있습니다 만, 함수 선언은 statements가 없습니다. 이 문제는 ECMA-262의 설명을 참조하십시오. .

    // badif(currentUser){functiontest(){console.log('Nope.');}}// goodvartest;if(currentUser){test=functiontest(){console.log('Yup.');};}
  • 매개 변수(parameter)에 arguments를 절대 지정하지 마십시오. 이것은 함수 범위로 전달 될arguments객체의 참조를 덮어 쓸 것입니다.

    // badfunctionnope(name,options,arguments){// ...stuff...}// goodfunctionyup(name,options,args){// ...stuff...}

    [↑]

  • 속성에 액세스하려면 도트.를 사용하십시오.

    varluke={jedi: true,age: 28};// badvarisJedi=luke['jedi'];// goodvarisJedi=luke.jedi;
  • 변수를 사용하여 속성에 접근하려면 대괄호[]을 사용하십시오.

    varluke={jedi: true,age: 28};functiongetProp(prop){returnluke[prop];}varisJedi=getProp('jedi');

    [↑]

  • 변수를 선언 할 때는 항상 var를 사용하십시오. 그렇지 않으면 전역 변수로 선언됩니다. 전역 네임 스페이스를 오염시키지 않도록 Captain Planet도 경고하고 있습니다.

    // badsuperPower=newSuperPower();// goodvarsuperPower=newSuperPower();
  • 여러 변수를 선언하려면 하나의 var를 사용하여 변수마다 줄바꿈하여 선언하십시오.

    // badvaritems=getItems();vargoSportsTeam=true;vardragonball='z';// goodvaritems=getItems(),goSportsTeam=true,dragonball='z';
  • 정의되지 않은 변수를 마지막으로 선언하십시오. 이것은 나중에 이미 할당된 변수 중 하나를 지정해야하는 경우에 유용합니다.

    // badvari,len,dragonball,items=getItems(),goSportsTeam=true;// badvari,items=getItems(),dragonball,goSportsTeam=true,len;// goodvaritems=getItems(),goSportsTeam=true,dragonball,length,i;
  • 변수의 할당은 스코프의 시작 부분에서 해주십시오. 이것은 변수 선언과 Hoisting 관련 문제를 해결합니다.

    // badfunction(){test();console.log('doing stuff..');//..other stuff..varname=getName();if(name==='test'){returnfalse;}returnname;}// goodfunction(){varname=getName();test();console.log('doing stuff..');//..other stuff..if(name==='test'){returnfalse;}returnname;}// badfunction(){varname=getName();if(!arguments.length){returnfalse;}returntrue;}// goodfunction(){if(!arguments.length){returnfalse;}varname=getName();returntrue;}

    [↑]

  • 해당 스코프의 시작 부분에 Hoist된 변수선언은 할당되지 않습니다.

    // (notDefined가 전역 변수에 존재하지 않는다고 가정했을 경우)// 이것은 동작하지 않습니다.functionexample(){console.log(notDefined);// => throws a ReferenceError}// 그 변수를 참조하는 코드 후에 그 변수를 선언 한 경우// 변수가 Hoist된 상태에서 작동합니다.// Note : `true`라는 값 자체는 Hoist되지 않습니다.functionexample(){console.log(declaredButNotAssigned);// => undefinedvardeclaredButNotAssigned=true;}// 인터 프린터는 변수 선언을 스코프의 시작 부분에 Hoist합니다.// 위의 예는 다음과 같이 다시 작성할 수 있습니다.functionexample(){vardeclaredButNotAssigned;console.log(declaredButNotAssigned);// => undefineddeclaredButNotAssigned=true;}
  • 익명 함수의 경우 함수가 할당되기 전에 변수가 Hoist될 수 있습니다.

    functionexample(){console.log(anonymous);// => undefinedanonymous();// => TypeError anonymous is not a functionvaranonymous=function(){console.log('anonymous function expression');};}
  • 명명 된 함수의 경우도 마찬가지로 변수가 Hoist될 수 있습니다. 함수 이름과 함수 본체는 Hoist되지 않습니다.

    functionexample(){console.log(named);// => undefinednamed();// => TypeError named is not a functionsuperPower();// => ReferenceError superPower is not definedvarnamed=functionsuperPower(){console.log('Flying');};}// 함수이름과 변수이름이 같은 경우에도 같은 일이 일어납니다.functionexample(){console.log(named);// => undefinednamed();// => TypeError named is not a functionvarnamed=functionnamed(){console.log('named');}}
  • 함수 선언은 함수이름과 함수본문이 Hoist됩니다.

    functionexample(){superPower();// => FlyingfunctionsuperPower(){console.log('Flying');}}
  • 더 자세한 정보는 Ben CherryJavaScript Scoping & Hoisting를 참조하십시오.

    [↑]

  • ==!= 보다는 ===!== 를 사용해 주십시오

  • 조건식은ToBoolean 메소드에 의해 엄밀하게 비교됩니다. 항상 이 간단한 규칙에 따라 주십시오.

    • Objectstrue 로 평가됩니다.
    • undefinedfalse 로 평가됩니다.
    • nullfalse 로 평가됩니다.
    • Booleansboolean형의 값 으로 평가됩니다.
    • Numberstrue 로 평가됩니다. 하지만 +0, -0, or NaN 의 경우는 false 입니다.
    • Stringstrue 로 평가됩니다. 하지만 빈문자 '' 의 경우는 false 입니다.
    if([0]){// true// Array는 Object 이므로 true 로 평가됩니다.}
  • 짧은형식을 사용하십시오.

    // badif(name!==''){// ...stuff...}// goodif(name){// ...stuff...}// badif(collection.length>0){// ...stuff...}// goodif(collection.length){// ...stuff...}
  • 더 자세한 정보는 Angus Croll 의 Truth Equality and JavaScript를 참고해 주십시오.

    [↑]

  • 복수행 블록은 중괄호 ({})를 사용하십시오.

    // badif(test)returnfalse;// goodif(test)returnfalse;// goodif(test){returnfalse;}// badfunction(){returnfalse;}// goodfunction(){returnfalse;}

    [↑]

  • 복수행의 코멘트는 /** ... */ 를 사용해 주십시오. 그 안에는 설명과 모든 매개 변수와 반환 값에 대한 형식과 값을 설명합니다.

    // bad// make() returns a new element// based on the passed in tag name//// @param <String> tag// @return <Element> elementfunctionmake(tag){// ...stuff...returnelement;}// good/** * make() returns a new element * based on the passed in tag name * * @param <String> tag * @return <Element> element */functionmake(tag){// ...stuff...returnelement;}
  • 한 줄 주석에는//를 사용하십시오. 코멘트를 추가하고 싶은 코드의 상단에 작성하십시오. 또한 주석 앞에 빈 줄을 넣어주십시오.

    // badvaractive=true;// is current tab// good// is current tabvaractive=true;// badfunctiongetType(){console.log('fetching type...');// set the default type to 'no type'vartype=this._type||'no type';returntype;}// goodfunctiongetType(){console.log('fetching type...');// set the default type to 'no type'vartype=this._type||'no type';returntype;}
  • 문제를 지적하고 재고를 촉구하거나 문제에 대한 해결책을 제시하는 등 의견의 앞에 FIXMETODO를 붙이는 것으로 다른 개발자의 빠른 이해를 도울 수 있습니다. 이러한 어떤 액션을 동반한다는 의미에서 일반 코멘트와는 다릅니다. 액션은 FIXME - 해결책이 필요 또는 TODO - 구현이 필요 입니다.

  • 문제에 대한 코멘트로 // FIXME :를 사용하십시오.

    functionCalculator(){// FIXME: 전역 변수를 사용해서는 안됩니다.total=0;returnthis;}
  • 문제 해결책에 대한 코멘트로 // TODO :를 사용하십시오.

    functionCalculator(){// TODO: total은 옵션 매개 변수로 설정되어야 함.this.total=0;returnthis;}

[↑]

  • 탭에는 공백 2개를 설정하십시오.

    // badfunction(){∙∙∙∙varname;}// badfunction(){∙varname;}// goodfunction(){∙∙varname;}
  • 중괄호({})의 앞에 공백을 하나 넣어주십시오.

    // badfunctiontest(){console.log('test');}// goodfunctiontest(){console.log('test');}// baddog.set('attr',{age: '1 year',breed: 'Bernese Mountain Dog'});// gooddog.set('attr',{age: '1 year',breed: 'Bernese Mountain Dog'});
  • 파일의 마지막에는 빈 줄을 하나 넣어주십시오.

    // bad(function(global){// ...stuff...})(this);
    // good(function(global){// ...stuff...})(this);
  • 메소드 체인이 길어지는 경우 적절히 들여쓰기(indentation) 하십시오.

    // bad$('#items').find('.selected').highlight().end().find('.open').updateCount();// good$('#items').find('.selected').highlight().end().find('.open').updateCount();// badvarleds=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);// goodvarleds=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);

    [↑]

  • 선두의 comma는 하지마십시오.

    // badvaronce,upon,aTime;// goodvaronce,upon,aTime;// badvarhero={firstName: 'Bob',lastName: 'Parr',heroName: 'Mr. Incredible',superPower: 'strength'};// goodvarhero={firstName: 'Bob',lastName: 'Parr',heroName: 'Mr. Incredible',superPower: 'strength'};
  • 말미의 불필요한 쉼표도 하지 마십시오. 이것은 IE6/7과 quirksmode의 IE9에서 문제를 일으킬 수 있습니다. 또한 ES3의 일부 구현에서 불필요한 쉼표가 있는 경우, 배열 길이를 추가합니다. 이것은 ES5에서 분명해졌습니다.(source):

    제 5 판에서는 말미의 불필요한 쉼표가 있는 ArrayInitialiser (배열 초기화 연산자)라도 배열에 길이를 추가하지 않는다는 사실을 명확히하고 있습니다. 이것은 제 3 판에서 의미적인 변경은 아닙니다만, 일부의 구현은 이전부터 이것을 오해하고 있었을지도 모릅니다.

    // badvarhero={firstName: 'Kevin',lastName: 'Flynn',};varheroes=['Batman','Superman',];// goodvarhero={firstName: 'Kevin',lastName: 'Flynn'};varheroes=['Batman','Superman'];

    [↑]

  • 네!(Yup.)

    // bad(function(){varname='Skywalker'returnname})()// good(function(){varname='Skywalker';returnname;})();// good;(function(){varname='Skywalker';returnname;})();

    [↑]

  • 문의 시작 부분에서 형을 강제합니다.

  • Strings:

    // => this.reviewScore = 9;// badvartotalScore=this.reviewScore+'';// goodvartotalScore=''+this.reviewScore;// badvartotalScore=''+this.reviewScore+' total score';// goodvartotalScore=this.reviewScore+' total score';
  • 숫자는parseInt를 사용하십시오. 항상 형변환을 위한 기수(radix)를 인수로 전달하십시오.

    varinputValue='4';// badvarval=newNumber(inputValue);// badvarval=+inputValue;// badvarval=inputValue>>0;// badvarval=parseInt(inputValue);// goodvarval=Number(inputValue);// goodvarval=parseInt(inputValue,10);
  • 어떤 이유에 의해 parseInt 가 병목이 되고, 성능적인 이유로 Bitshift를 사용할 필요가 있을 경우, 하려고 하는것에 대해, why(왜)와 what(무엇)의 설명을 코멘트로 남겨주십시오.

    // good/** * parseInt가 병목을 일으키므로 * Bitshift로 문자열을 수치로 강제적으로 변환하는 방법으로 * 성능을 개선시킵니다. */varval=inputValue>>0;
  • Booleans:

    varage=0;// badvarhasAge=newBoolean(age);// goodvarhasAge=Boolean(age);// goodvarhasAge=!!age;

    [↑]

  • 한문자 이름은 피하십시오. 이름에서 의도를 읽을 수 있도록 하십시오.

    // badfunctionq(){// ...stuff...}// goodfunctionquery(){// ..stuff..}
  • Object, 함수, 그리고 인스턴스로는 camelCase를 사용하십시오.

    // badvarOBJEcttsssss={};varthis_is_my_object={};varthis-is-my-object={};functionc(){};varu=newuser({name: 'Bob Parr'});// goodvarthisIsMyObject={};functionthisIsMyFunction(){};varuser=newUser({name: 'Bob Parr'});
  • Class와 생성자에는 PascalCase를 사용하십시오.

    // badfunctionuser(options){this.name=options.name;}varbad=newuser({name: 'nope'});// goodfunctionUser(options){this.name=options.name;}vargood=newUser({name: 'yup'});
  • private 속성 이름은 밑줄 _ 을 사용하십시오.

    // badthis.__firstName__='Panda';this.firstName_='Panda';// goodthis._firstName='Panda';
  • this의 참조를 저장할 때 _this 를 사용하십시오.

    // badfunction(){varself=this;returnfunction(){console.log(self);};}// badfunction(){varthat=this;returnfunction(){console.log(that);};}// goodfunction(){var_this=this;returnfunction(){console.log(_this);};}
  • 함수에 이름을 붙여주십시오. 이것은 stack traces를 추적하기 쉽게하기 때문입니다.

    // badvarlog=function(msg){console.log(msg);};// goodvarlog=functionlog(msg){console.log(msg);};

    [↑]

  • 속성을 위한 접근자(Accessor) 함수는 필요 없습니다.

  • 접근자 함수가 필요한 경우 getVal() 이나 setVal('hello') 라고 사용합니다.

    // baddragon.age();// gooddragon.getAge();// baddragon.age(25);// gooddragon.setAge(25);
  • 속성이 boolean의 경우 isVal() 이나 hasVal() 라고 사용합니다.

    // badif(!dragon.age()){returnfalse;}// goodif(!dragon.hasAge()){returnfalse;}
  • 일관된다면 get() 이나 set() 이라는 함수를 작성해도 좋습니다.

    functionJedi(options){options||(options={});varlightsaber=options.lightsaber||'blue';this.set('lightsaber',lightsaber);}Jedi.prototype.set=function(key,val){this[key]=val;};Jedi.prototype.get=function(key){returnthis[key];};

    [↑]

  • 새 Object에서 프로토타입을 재정의하는 것이 아니라, 프로토타입 객체에 메서드를 추가해 주십시오. 프로토타입을 재정의하면 상속이 불가능합니다. 프로토타입을 리셋하는것으로 베이스 클래스를 재정의 할 수 있습니다.

    functionJedi(){console.log('new jedi');}// badJedi.prototype={fight: functionfight(){console.log('fighting');},block: functionblock(){console.log('blocking');}};// goodJedi.prototype.fight=functionfight(){console.log('fighting');};Jedi.prototype.block=functionblock(){console.log('blocking');};
  • 메소드의 반환 값으로 this를 반환함으로써 메소드 체인을 할 수 있습니다.

    // badJedi.prototype.jump=function(){this.jumping=true;returntrue;};Jedi.prototype.setHeight=function(height){this.height=height;};varluke=newJedi();luke.jump();// => trueluke.setHeight(20)// => undefined// goodJedi.prototype.jump=function(){this.jumping=true;returnthis;};Jedi.prototype.setHeight=function(height){this.height=height;returnthis;};varluke=newJedi();luke.jump().setHeight(20);
  • 독자적인 toString()을 만들 수도 있지만 올바르게 작동하는지, 부작용이 없는 것만은 확인해 주십시오.

    functionJedi(options){options||(options={});this.name=options.name||'no name';}Jedi.prototype.getName=functiongetName(){returnthis.name;};Jedi.prototype.toString=functiontoString(){return'Jedi - '+this.getName();};

    [↑]

  • (DOM 이벤트나 Backbone events와 같은 고유의) 이벤트 탑재체(payloads)의 값을 전달하는 경우 원시 값(raw value) 대신 해시 인수(hash)를 전달합니다. 이렇게하는 것으로 나중에 개발자가 이벤트와 관련된 모든 핸들러를 찾아 업데이트 하지 않고 이벤트 탑재체(payloads)에 값을 추가 할 수 있습니다. 예를 들어, 이것 대신 :

    // bad$(this).trigger('listingUpdated',listing.id);
    ...
    $(this).on('listingUpdated',function(e,listingId){// do something with listingId});

    이쪽을 선호합니다.:

    // good$(this).trigger('listingUpdated',{listingId : listing.id});
    ...
    $(this).on('listingUpdated',function(e,data){// do something with data.listingId});

[↑]

  • 모듈의 시작은 ! 로 시작하십시오. 이것은 문말에 세미콜론을 넣는것을 잊은 모듈을 연결할때 런타임 오류가 발생하지 않기 때문입니다.

  • 파일 이름은 camelCase를 사용하여 같은 이름의 폴더에 저장해주십시오. 또한 단독으로 공개할 경우 이름을 일치시켜주십시오.

  • noConflict() 라는 명칭으로 (이름이 겹쳐 덮어 써지기 전의) 모듈을 반환하는 메서드를 추가해주십시오.

  • 항상 모듈의 시작 부분에서 'use strict';를 선언해주십시오.

    // fancyInput/fancyInput.js!function(global){'use strict';varpreviousFancyInput=global.FancyInput;functionFancyInput(options){this.options=options||{};}FancyInput.noConflict=functionnoConflict(){global.FancyInput=previousFancyInput;returnFancyInput;};global.FancyInput=FancyInput;}(this);

    [↑]

  • jQuery Object의 변수 앞에는 $을 부여해 주십시오.

    // badvarsidebar=$('.sidebar');// goodvar$sidebar=$('.sidebar');
  • jQuery 쿼리결과를 캐시해주십시오.

    // badfunctionsetSidebar(){$('.sidebar').hide();// ...stuff...$('.sidebar').css({'background-color': 'pink'});}// goodfunctionsetSidebar(){var$sidebar=$('.sidebar');$sidebar.hide();// ...stuff...$sidebar.css({'background-color': 'pink'});}
  • DOM 검색은 Cascading $('.sidebar ul') 이나 parent > child $('.sidebar > ul') 를 사용해주십시오. jsPerf

  • jQuery Object 검색은 스코프가 붙은 find를 사용해주십시오.

    // bad$('ul','.sidebar').hide();// bad$('.sidebar').find('ul').hide();// good$('.sidebar ul').hide();// good$('.sidebar > ul').hide();// good$sidebar.find('ul');

    [↑]

[↑]

  • 네!(Yup.)

    function(){returntrue;}

    [↑]

[↑]

Read This

Other Styleguides

Other Styles

Further Reading

Books

Blogs

[↑]

This is a list of organizations that are using this style guide. Send us a pull request or open an issue and we'll add you to the list.

This style guide is also available in other languages:

(The MIT License)

Copyright (c) 2012 Airbnb

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

[↑]

};

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' javascript-style-guide/es5.md at master · tipjs/javascript-style-guide · GitHub
Skip to content

Latest commit

History

History
1524 lines (1122 loc) · 39.4 KB

File metadata and controls

1524 lines (1122 loc) · 39.4 KB

원문:https://github.com/airbnb/javascript

Airbnb JavaScript 스타일 가이드() {

  1. Types
  2. Objects
  3. Arrays
  4. Strings
  5. Functions
  6. Properties
  7. Variables
  8. Hoisting
  9. Conditional Expressions & Equality
  10. Blocks
  11. Comments
  12. Whitespace
  13. Commas
  14. Semicolons
  15. Type Casting & Coercion
  16. Naming Conventions
  17. Accessors
  18. Constructors
  19. Events
  20. Modules
  21. jQuery
  22. ES5 Compatibility
  23. Testing
  24. Performance
  25. Resources
  26. In the Wild
  27. Translation
  28. The JavaScript Style Guide Guide
  29. Contributors
  30. License
  • Primitives: primitive type은 그 값을 직접 조작합니다.

    • string
    • number
    • boolean
    • null
    • undefined
    varfoo=1,bar=foo;bar=9;console.log(foo,bar);// => 1, 9
  • Complex: 참조형(Complex)은 참조를 통해 값을 조작합니다.

    • object
    • array
    • function
    varfoo=[1,2],bar=foo;bar[0]=9;console.log(foo[0],bar[0]);// => 9, 9

    [↑]

  • Object를 만들 때는 리터럴 구문을 사용하십시오.

    // badvaritem=newObject();// goodvaritem={};
  • 예약어(reserved words)를 키로 사용하지 마십시오. 이것은 IE8에서 동작하지 않습니다. More info

    // badvarsuperman={default: {clark: 'kent'},private: true};// goodvarsuperman={defaults: {clark: 'kent'},hidden: true};
  • 예약어 대신 알기 쉬운 동의어(readable synonyms)를 사용하십시오.

    // badvarsuperman={class: 'alien'};// badvarsuperman={klass: 'alien'};// goodvarsuperman={type: 'alien'};

    [↑]

  • 배열을 만들 때 리터럴 구문을 사용하십시오.

    // badvaritems=newArray();// goodvaritems=[];
  • 길이를 알 수없는 경우는 Array#push를 사용하십시오.

    varsomeStack=[];// badsomeStack[someStack.length]='abracadabra';// goodsomeStack.push('abracadabra');
  • 배열을 복사 할 필요가있는 경우 Array#slice를 사용하십시오. jsPerf

    varlen=items.length,itemsCopy=[],i;// badfor(i=0;i<len;i++){itemsCopy[i]=items[i];}// gooditemsCopy=items.slice();
  • Array와 비슷한(Array-Like)한 Object를 Array에 변환하는 경우는 Array#slice를 사용하십시오.

    functiontrigger(){varargs=Array.prototype.slice.call(arguments);
    ...
    }

[↑]

  • 문자열은 작은 따옴표''를 사용하십시오.

    // badvarname="Bob Parr";// goodvarname='Bob Parr';// badvarfullName="Bob "+this.lastName;// goodvarfullName='Bob '+this.lastName;
  • 80 문자 이상의 문자열은 문자열 연결을 사용하여 여러 줄에 걸쳐 기술 할 필요가 있습니다.

  • Note : 문자열 연결을 많이하면 성능에 영향을 줄 수 있습니다. jsPerf & Discussion

    // badvarerrorMessage='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.';// badvarerrorMessage='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.';// goodvarerrorMessage='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.';
  • 프로그램에서 문자열을 생성 할 필요가 있는 경우 (특히 IE는) 문자열 연결 대신 Array#join을 사용하십시오. 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;// badfunctioninbox(messages){items='<ul>';for(i=0;i<length;i++){items+='<li>'+messages[i].message+'</li>';}returnitems+'</ul>';}// goodfunctioninbox(messages){items=[];for(i=0;i<length;i++){items[i]=messages[i].message;}return'<ul><li>'+items.join('</li><li>')+'</li></ul>';}

    [↑]

  • 함수식(Function expressions)

    // 익명함수식(anonymous function expression)varanonymous=function(){returntrue;};// 명명된 함수식(named function expression)varnamed=functionnamed(){returntrue;};// 즉시실행 함수식(immediately-invoked function expression (IIFE))(function(){console.log('Welcome to the Internet. Please follow me.');})();
  • (if 및 while 등) 블록 내에서 변수에 함수를 할당하는 대신 함수를 선언하지 마십시오. 브라우저는 허용하지만 (마치 'bad news bears'처럼) 모두 다른 방식으로 해석됩니다.

  • Note: ECMA-262에서는block은 statements의 목록에 정의되어 있습니다 만, 함수 선언은 statements가 없습니다. 이 문제는 ECMA-262의 설명을 참조하십시오. .

    // badif(currentUser){functiontest(){console.log('Nope.');}}// goodvartest;if(currentUser){test=functiontest(){console.log('Yup.');};}
  • 매개 변수(parameter)에 arguments를 절대 지정하지 마십시오. 이것은 함수 범위로 전달 될arguments객체의 참조를 덮어 쓸 것입니다.

    // badfunctionnope(name,options,arguments){// ...stuff...}// goodfunctionyup(name,options,args){// ...stuff...}

    [↑]

  • 속성에 액세스하려면 도트.를 사용하십시오.

    varluke={jedi: true,age: 28};// badvarisJedi=luke['jedi'];// goodvarisJedi=luke.jedi;
  • 변수를 사용하여 속성에 접근하려면 대괄호[]을 사용하십시오.

    varluke={jedi: true,age: 28};functiongetProp(prop){returnluke[prop];}varisJedi=getProp('jedi');

    [↑]

  • 변수를 선언 할 때는 항상 var를 사용하십시오. 그렇지 않으면 전역 변수로 선언됩니다. 전역 네임 스페이스를 오염시키지 않도록 Captain Planet도 경고하고 있습니다.

    // badsuperPower=newSuperPower();// goodvarsuperPower=newSuperPower();
  • 여러 변수를 선언하려면 하나의 var를 사용하여 변수마다 줄바꿈하여 선언하십시오.

    // badvaritems=getItems();vargoSportsTeam=true;vardragonball='z';// goodvaritems=getItems(),goSportsTeam=true,dragonball='z';
  • 정의되지 않은 변수를 마지막으로 선언하십시오. 이것은 나중에 이미 할당된 변수 중 하나를 지정해야하는 경우에 유용합니다.

    // badvari,len,dragonball,items=getItems(),goSportsTeam=true;// badvari,items=getItems(),dragonball,goSportsTeam=true,len;// goodvaritems=getItems(),goSportsTeam=true,dragonball,length,i;
  • 변수의 할당은 스코프의 시작 부분에서 해주십시오. 이것은 변수 선언과 Hoisting 관련 문제를 해결합니다.

    // badfunction(){test();console.log('doing stuff..');//..other stuff..varname=getName();if(name==='test'){returnfalse;}returnname;}// goodfunction(){varname=getName();test();console.log('doing stuff..');//..other stuff..if(name==='test'){returnfalse;}returnname;}// badfunction(){varname=getName();if(!arguments.length){returnfalse;}returntrue;}// goodfunction(){if(!arguments.length){returnfalse;}varname=getName();returntrue;}

    [↑]

  • 해당 스코프의 시작 부분에 Hoist된 변수선언은 할당되지 않습니다.

    // (notDefined가 전역 변수에 존재하지 않는다고 가정했을 경우)// 이것은 동작하지 않습니다.functionexample(){console.log(notDefined);// => throws a ReferenceError}// 그 변수를 참조하는 코드 후에 그 변수를 선언 한 경우// 변수가 Hoist된 상태에서 작동합니다.// Note : `true`라는 값 자체는 Hoist되지 않습니다.functionexample(){console.log(declaredButNotAssigned);// => undefinedvardeclaredButNotAssigned=true;}// 인터 프린터는 변수 선언을 스코프의 시작 부분에 Hoist합니다.// 위의 예는 다음과 같이 다시 작성할 수 있습니다.functionexample(){vardeclaredButNotAssigned;console.log(declaredButNotAssigned);// => undefineddeclaredButNotAssigned=true;}
  • 익명 함수의 경우 함수가 할당되기 전에 변수가 Hoist될 수 있습니다.

    functionexample(){console.log(anonymous);// => undefinedanonymous();// => TypeError anonymous is not a functionvaranonymous=function(){console.log('anonymous function expression');};}
  • 명명 된 함수의 경우도 마찬가지로 변수가 Hoist될 수 있습니다. 함수 이름과 함수 본체는 Hoist되지 않습니다.

    functionexample(){console.log(named);// => undefinednamed();// => TypeError named is not a functionsuperPower();// => ReferenceError superPower is not definedvarnamed=functionsuperPower(){console.log('Flying');};}// 함수이름과 변수이름이 같은 경우에도 같은 일이 일어납니다.functionexample(){console.log(named);// => undefinednamed();// => TypeError named is not a functionvarnamed=functionnamed(){console.log('named');}}
  • 함수 선언은 함수이름과 함수본문이 Hoist됩니다.

    functionexample(){superPower();// => FlyingfunctionsuperPower(){console.log('Flying');}}
  • 더 자세한 정보는 Ben CherryJavaScript Scoping & Hoisting를 참조하십시오.

    [↑]

  • ==!= 보다는 ===!== 를 사용해 주십시오

  • 조건식은ToBoolean 메소드에 의해 엄밀하게 비교됩니다. 항상 이 간단한 규칙에 따라 주십시오.

    • Objectstrue 로 평가됩니다.
    • undefinedfalse 로 평가됩니다.
    • nullfalse 로 평가됩니다.
    • Booleansboolean형의 값 으로 평가됩니다.
    • Numberstrue 로 평가됩니다. 하지만 +0, -0, or NaN 의 경우는 false 입니다.
    • Stringstrue 로 평가됩니다. 하지만 빈문자 '' 의 경우는 false 입니다.
    if([0]){// true// Array는 Object 이므로 true 로 평가됩니다.}
  • 짧은형식을 사용하십시오.

    // badif(name!==''){// ...stuff...}// goodif(name){// ...stuff...}// badif(collection.length>0){// ...stuff...}// goodif(collection.length){// ...stuff...}
  • 더 자세한 정보는 Angus Croll 의 Truth Equality and JavaScript를 참고해 주십시오.

    [↑]

  • 복수행 블록은 중괄호 ({})를 사용하십시오.

    // badif(test)returnfalse;// goodif(test)returnfalse;// goodif(test){returnfalse;}// badfunction(){returnfalse;}// goodfunction(){returnfalse;}

    [↑]

  • 복수행의 코멘트는 /** ... */ 를 사용해 주십시오. 그 안에는 설명과 모든 매개 변수와 반환 값에 대한 형식과 값을 설명합니다.

    // bad// make() returns a new element// based on the passed in tag name//// @param <String> tag// @return <Element> elementfunctionmake(tag){// ...stuff...returnelement;}// good/** * make() returns a new element * based on the passed in tag name * * @param <String> tag * @return <Element> element */functionmake(tag){// ...stuff...returnelement;}
  • 한 줄 주석에는//를 사용하십시오. 코멘트를 추가하고 싶은 코드의 상단에 작성하십시오. 또한 주석 앞에 빈 줄을 넣어주십시오.

    // badvaractive=true;// is current tab// good// is current tabvaractive=true;// badfunctiongetType(){console.log('fetching type...');// set the default type to 'no type'vartype=this._type||'no type';returntype;}// goodfunctiongetType(){console.log('fetching type...');// set the default type to 'no type'vartype=this._type||'no type';returntype;}
  • 문제를 지적하고 재고를 촉구하거나 문제에 대한 해결책을 제시하는 등 의견의 앞에 FIXMETODO를 붙이는 것으로 다른 개발자의 빠른 이해를 도울 수 있습니다. 이러한 어떤 액션을 동반한다는 의미에서 일반 코멘트와는 다릅니다. 액션은 FIXME - 해결책이 필요 또는 TODO - 구현이 필요 입니다.

  • 문제에 대한 코멘트로 // FIXME :를 사용하십시오.

    functionCalculator(){// FIXME: 전역 변수를 사용해서는 안됩니다.total=0;returnthis;}
  • 문제 해결책에 대한 코멘트로 // TODO :를 사용하십시오.

    functionCalculator(){// TODO: total은 옵션 매개 변수로 설정되어야 함.this.total=0;returnthis;}

[↑]

  • 탭에는 공백 2개를 설정하십시오.

    // badfunction(){∙∙∙∙varname;}// badfunction(){∙varname;}// goodfunction(){∙∙varname;}
  • 중괄호({})의 앞에 공백을 하나 넣어주십시오.

    // badfunctiontest(){console.log('test');}// goodfunctiontest(){console.log('test');}// baddog.set('attr',{age: '1 year',breed: 'Bernese Mountain Dog'});// gooddog.set('attr',{age: '1 year',breed: 'Bernese Mountain Dog'});
  • 파일의 마지막에는 빈 줄을 하나 넣어주십시오.

    // bad(function(global){// ...stuff...})(this);
    // good(function(global){// ...stuff...})(this);
  • 메소드 체인이 길어지는 경우 적절히 들여쓰기(indentation) 하십시오.

    // bad$('#items').find('.selected').highlight().end().find('.open').updateCount();// good$('#items').find('.selected').highlight().end().find('.open').updateCount();// badvarleds=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);// goodvarleds=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);

    [↑]

  • 선두의 comma는 하지마십시오.

    // badvaronce,upon,aTime;// goodvaronce,upon,aTime;// badvarhero={firstName: 'Bob',lastName: 'Parr',heroName: 'Mr. Incredible',superPower: 'strength'};// goodvarhero={firstName: 'Bob',lastName: 'Parr',heroName: 'Mr. Incredible',superPower: 'strength'};
  • 말미의 불필요한 쉼표도 하지 마십시오. 이것은 IE6/7과 quirksmode의 IE9에서 문제를 일으킬 수 있습니다. 또한 ES3의 일부 구현에서 불필요한 쉼표가 있는 경우, 배열 길이를 추가합니다. 이것은 ES5에서 분명해졌습니다.(source):

    제 5 판에서는 말미의 불필요한 쉼표가 있는 ArrayInitialiser (배열 초기화 연산자)라도 배열에 길이를 추가하지 않는다는 사실을 명확히하고 있습니다. 이것은 제 3 판에서 의미적인 변경은 아닙니다만, 일부의 구현은 이전부터 이것을 오해하고 있었을지도 모릅니다.

    // badvarhero={firstName: 'Kevin',lastName: 'Flynn',};varheroes=['Batman','Superman',];// goodvarhero={firstName: 'Kevin',lastName: 'Flynn'};varheroes=['Batman','Superman'];

    [↑]

  • 네!(Yup.)

    // bad(function(){varname='Skywalker'returnname})()// good(function(){varname='Skywalker';returnname;})();// good;(function(){varname='Skywalker';returnname;})();

    [↑]

  • 문의 시작 부분에서 형을 강제합니다.

  • Strings:

    // => this.reviewScore = 9;// badvartotalScore=this.reviewScore+'';// goodvartotalScore=''+this.reviewScore;// badvartotalScore=''+this.reviewScore+' total score';// goodvartotalScore=this.reviewScore+' total score';
  • 숫자는parseInt를 사용하십시오. 항상 형변환을 위한 기수(radix)를 인수로 전달하십시오.

    varinputValue='4';// badvarval=newNumber(inputValue);// badvarval=+inputValue;// badvarval=inputValue>>0;// badvarval=parseInt(inputValue);// goodvarval=Number(inputValue);// goodvarval=parseInt(inputValue,10);
  • 어떤 이유에 의해 parseInt 가 병목이 되고, 성능적인 이유로 Bitshift를 사용할 필요가 있을 경우, 하려고 하는것에 대해, why(왜)와 what(무엇)의 설명을 코멘트로 남겨주십시오.

    // good/** * parseInt가 병목을 일으키므로 * Bitshift로 문자열을 수치로 강제적으로 변환하는 방법으로 * 성능을 개선시킵니다. */varval=inputValue>>0;
  • Booleans:

    varage=0;// badvarhasAge=newBoolean(age);// goodvarhasAge=Boolean(age);// goodvarhasAge=!!age;

    [↑]

  • 한문자 이름은 피하십시오. 이름에서 의도를 읽을 수 있도록 하십시오.

    // badfunctionq(){// ...stuff...}// goodfunctionquery(){// ..stuff..}
  • Object, 함수, 그리고 인스턴스로는 camelCase를 사용하십시오.

    // badvarOBJEcttsssss={};varthis_is_my_object={};varthis-is-my-object={};functionc(){};varu=newuser({name: 'Bob Parr'});// goodvarthisIsMyObject={};functionthisIsMyFunction(){};varuser=newUser({name: 'Bob Parr'});
  • Class와 생성자에는 PascalCase를 사용하십시오.

    // badfunctionuser(options){this.name=options.name;}varbad=newuser({name: 'nope'});// goodfunctionUser(options){this.name=options.name;}vargood=newUser({name: 'yup'});
  • private 속성 이름은 밑줄 _ 을 사용하십시오.

    // badthis.__firstName__='Panda';this.firstName_='Panda';// goodthis._firstName='Panda';
  • this의 참조를 저장할 때 _this 를 사용하십시오.

    // badfunction(){varself=this;returnfunction(){console.log(self);};}// badfunction(){varthat=this;returnfunction(){console.log(that);};}// goodfunction(){var_this=this;returnfunction(){console.log(_this);};}
  • 함수에 이름을 붙여주십시오. 이것은 stack traces를 추적하기 쉽게하기 때문입니다.

    // badvarlog=function(msg){console.log(msg);};// goodvarlog=functionlog(msg){console.log(msg);};

    [↑]

  • 속성을 위한 접근자(Accessor) 함수는 필요 없습니다.

  • 접근자 함수가 필요한 경우 getVal() 이나 setVal('hello') 라고 사용합니다.

    // baddragon.age();// gooddragon.getAge();// baddragon.age(25);// gooddragon.setAge(25);
  • 속성이 boolean의 경우 isVal() 이나 hasVal() 라고 사용합니다.

    // badif(!dragon.age()){returnfalse;}// goodif(!dragon.hasAge()){returnfalse;}
  • 일관된다면 get() 이나 set() 이라는 함수를 작성해도 좋습니다.

    functionJedi(options){options||(options={});varlightsaber=options.lightsaber||'blue';this.set('lightsaber',lightsaber);}Jedi.prototype.set=function(key,val){this[key]=val;};Jedi.prototype.get=function(key){returnthis[key];};

    [↑]

  • 새 Object에서 프로토타입을 재정의하는 것이 아니라, 프로토타입 객체에 메서드를 추가해 주십시오. 프로토타입을 재정의하면 상속이 불가능합니다. 프로토타입을 리셋하는것으로 베이스 클래스를 재정의 할 수 있습니다.

    functionJedi(){console.log('new jedi');}// badJedi.prototype={fight: functionfight(){console.log('fighting');},block: functionblock(){console.log('blocking');}};// goodJedi.prototype.fight=functionfight(){console.log('fighting');};Jedi.prototype.block=functionblock(){console.log('blocking');};
  • 메소드의 반환 값으로 this를 반환함으로써 메소드 체인을 할 수 있습니다.

    // badJedi.prototype.jump=function(){this.jumping=true;returntrue;};Jedi.prototype.setHeight=function(height){this.height=height;};varluke=newJedi();luke.jump();// => trueluke.setHeight(20)// => undefined// goodJedi.prototype.jump=function(){this.jumping=true;returnthis;};Jedi.prototype.setHeight=function(height){this.height=height;returnthis;};varluke=newJedi();luke.jump().setHeight(20);
  • 독자적인 toString()을 만들 수도 있지만 올바르게 작동하는지, 부작용이 없는 것만은 확인해 주십시오.

    functionJedi(options){options||(options={});this.name=options.name||'no name';}Jedi.prototype.getName=functiongetName(){returnthis.name;};Jedi.prototype.toString=functiontoString(){return'Jedi - '+this.getName();};

    [↑]

  • (DOM 이벤트나 Backbone events와 같은 고유의) 이벤트 탑재체(payloads)의 값을 전달하는 경우 원시 값(raw value) 대신 해시 인수(hash)를 전달합니다. 이렇게하는 것으로 나중에 개발자가 이벤트와 관련된 모든 핸들러를 찾아 업데이트 하지 않고 이벤트 탑재체(payloads)에 값을 추가 할 수 있습니다. 예를 들어, 이것 대신 :

    // bad$(this).trigger('listingUpdated',listing.id);
    ...
    $(this).on('listingUpdated',function(e,listingId){// do something with listingId});

    이쪽을 선호합니다.:

    // good$(this).trigger('listingUpdated',{listingId : listing.id});
    ...
    $(this).on('listingUpdated',function(e,data){// do something with data.listingId});

[↑]

  • 모듈의 시작은 ! 로 시작하십시오. 이것은 문말에 세미콜론을 넣는것을 잊은 모듈을 연결할때 런타임 오류가 발생하지 않기 때문입니다.

  • 파일 이름은 camelCase를 사용하여 같은 이름의 폴더에 저장해주십시오. 또한 단독으로 공개할 경우 이름을 일치시켜주십시오.

  • noConflict() 라는 명칭으로 (이름이 겹쳐 덮어 써지기 전의) 모듈을 반환하는 메서드를 추가해주십시오.

  • 항상 모듈의 시작 부분에서 'use strict';를 선언해주십시오.

    // fancyInput/fancyInput.js!function(global){'use strict';varpreviousFancyInput=global.FancyInput;functionFancyInput(options){this.options=options||{};}FancyInput.noConflict=functionnoConflict(){global.FancyInput=previousFancyInput;returnFancyInput;};global.FancyInput=FancyInput;}(this);

    [↑]

  • jQuery Object의 변수 앞에는 $을 부여해 주십시오.

    // badvarsidebar=$('.sidebar');// goodvar$sidebar=$('.sidebar');
  • jQuery 쿼리결과를 캐시해주십시오.

    // badfunctionsetSidebar(){$('.sidebar').hide();// ...stuff...$('.sidebar').css({'background-color': 'pink'});}// goodfunctionsetSidebar(){var$sidebar=$('.sidebar');$sidebar.hide();// ...stuff...$sidebar.css({'background-color': 'pink'});}
  • DOM 검색은 Cascading $('.sidebar ul') 이나 parent > child $('.sidebar > ul') 를 사용해주십시오. jsPerf

  • jQuery Object 검색은 스코프가 붙은 find를 사용해주십시오.

    // bad$('ul','.sidebar').hide();// bad$('.sidebar').find('ul').hide();// good$('.sidebar ul').hide();// good$('.sidebar > ul').hide();// good$sidebar.find('ul');

    [↑]

[↑]

  • 네!(Yup.)

    function(){returntrue;}

    [↑]

[↑]

Read This

Other Styleguides

Other Styles

Further Reading

Books

Blogs

[↑]

This is a list of organizations that are using this style guide. Send us a pull request or open an issue and we'll add you to the list.

This style guide is also available in other languages:

(The MIT License)

Copyright (c) 2012 Airbnb

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

[↑]

};

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' javascript-style-guide/es5.md at master · tipjs/javascript-style-guide · GitHub
Skip to content

Latest commit

History

History
1524 lines (1122 loc) · 39.4 KB

File metadata and controls

1524 lines (1122 loc) · 39.4 KB

원문:https://github.com/airbnb/javascript

Airbnb JavaScript 스타일 가이드() {

  1. Types
  2. Objects
  3. Arrays
  4. Strings
  5. Functions
  6. Properties
  7. Variables
  8. Hoisting
  9. Conditional Expressions & Equality
  10. Blocks
  11. Comments
  12. Whitespace
  13. Commas
  14. Semicolons
  15. Type Casting & Coercion
  16. Naming Conventions
  17. Accessors
  18. Constructors
  19. Events
  20. Modules
  21. jQuery
  22. ES5 Compatibility
  23. Testing
  24. Performance
  25. Resources
  26. In the Wild
  27. Translation
  28. The JavaScript Style Guide Guide
  29. Contributors
  30. License
  • Primitives: primitive type은 그 값을 직접 조작합니다.

    • string
    • number
    • boolean
    • null
    • undefined
    varfoo=1,bar=foo;bar=9;console.log(foo,bar);// => 1, 9
  • Complex: 참조형(Complex)은 참조를 통해 값을 조작합니다.

    • object
    • array
    • function
    varfoo=[1,2],bar=foo;bar[0]=9;console.log(foo[0],bar[0]);// => 9, 9

    [↑]

  • Object를 만들 때는 리터럴 구문을 사용하십시오.

    // badvaritem=newObject();// goodvaritem={};
  • 예약어(reserved words)를 키로 사용하지 마십시오. 이것은 IE8에서 동작하지 않습니다. More info

    // badvarsuperman={default: {clark: 'kent'},private: true};// goodvarsuperman={defaults: {clark: 'kent'},hidden: true};
  • 예약어 대신 알기 쉬운 동의어(readable synonyms)를 사용하십시오.

    // badvarsuperman={class: 'alien'};// badvarsuperman={klass: 'alien'};// goodvarsuperman={type: 'alien'};

    [↑]

  • 배열을 만들 때 리터럴 구문을 사용하십시오.

    // badvaritems=newArray();// goodvaritems=[];
  • 길이를 알 수없는 경우는 Array#push를 사용하십시오.

    varsomeStack=[];// badsomeStack[someStack.length]='abracadabra';// goodsomeStack.push('abracadabra');
  • 배열을 복사 할 필요가있는 경우 Array#slice를 사용하십시오. jsPerf

    varlen=items.length,itemsCopy=[],i;// badfor(i=0;i<len;i++){itemsCopy[i]=items[i];}// gooditemsCopy=items.slice();
  • Array와 비슷한(Array-Like)한 Object를 Array에 변환하는 경우는 Array#slice를 사용하십시오.

    functiontrigger(){varargs=Array.prototype.slice.call(arguments);
    ...
    }

[↑]

  • 문자열은 작은 따옴표''를 사용하십시오.

    // badvarname="Bob Parr";// goodvarname='Bob Parr';// badvarfullName="Bob "+this.lastName;// goodvarfullName='Bob '+this.lastName;
  • 80 문자 이상의 문자열은 문자열 연결을 사용하여 여러 줄에 걸쳐 기술 할 필요가 있습니다.

  • Note : 문자열 연결을 많이하면 성능에 영향을 줄 수 있습니다. jsPerf & Discussion

    // badvarerrorMessage='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.';// badvarerrorMessage='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.';// goodvarerrorMessage='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.';
  • 프로그램에서 문자열을 생성 할 필요가 있는 경우 (특히 IE는) 문자열 연결 대신 Array#join을 사용하십시오. 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;// badfunctioninbox(messages){items='<ul>';for(i=0;i<length;i++){items+='<li>'+messages[i].message+'</li>';}returnitems+'</ul>';}// goodfunctioninbox(messages){items=[];for(i=0;i<length;i++){items[i]=messages[i].message;}return'<ul><li>'+items.join('</li><li>')+'</li></ul>';}

    [↑]

  • 함수식(Function expressions)

    // 익명함수식(anonymous function expression)varanonymous=function(){returntrue;};// 명명된 함수식(named function expression)varnamed=functionnamed(){returntrue;};// 즉시실행 함수식(immediately-invoked function expression (IIFE))(function(){console.log('Welcome to the Internet. Please follow me.');})();
  • (if 및 while 등) 블록 내에서 변수에 함수를 할당하는 대신 함수를 선언하지 마십시오. 브라우저는 허용하지만 (마치 'bad news bears'처럼) 모두 다른 방식으로 해석됩니다.

  • Note: ECMA-262에서는block은 statements의 목록에 정의되어 있습니다 만, 함수 선언은 statements가 없습니다. 이 문제는 ECMA-262의 설명을 참조하십시오. .

    // badif(currentUser){functiontest(){console.log('Nope.');}}// goodvartest;if(currentUser){test=functiontest(){console.log('Yup.');};}
  • 매개 변수(parameter)에 arguments를 절대 지정하지 마십시오. 이것은 함수 범위로 전달 될arguments객체의 참조를 덮어 쓸 것입니다.

    // badfunctionnope(name,options,arguments){// ...stuff...}// goodfunctionyup(name,options,args){// ...stuff...}

    [↑]

  • 속성에 액세스하려면 도트.를 사용하십시오.

    varluke={jedi: true,age: 28};// badvarisJedi=luke['jedi'];// goodvarisJedi=luke.jedi;
  • 변수를 사용하여 속성에 접근하려면 대괄호[]을 사용하십시오.

    varluke={jedi: true,age: 28};functiongetProp(prop){returnluke[prop];}varisJedi=getProp('jedi');

    [↑]

  • 변수를 선언 할 때는 항상 var를 사용하십시오. 그렇지 않으면 전역 변수로 선언됩니다. 전역 네임 스페이스를 오염시키지 않도록 Captain Planet도 경고하고 있습니다.

    // badsuperPower=newSuperPower();// goodvarsuperPower=newSuperPower();
  • 여러 변수를 선언하려면 하나의 var를 사용하여 변수마다 줄바꿈하여 선언하십시오.

    // badvaritems=getItems();vargoSportsTeam=true;vardragonball='z';// goodvaritems=getItems(),goSportsTeam=true,dragonball='z';
  • 정의되지 않은 변수를 마지막으로 선언하십시오. 이것은 나중에 이미 할당된 변수 중 하나를 지정해야하는 경우에 유용합니다.

    // badvari,len,dragonball,items=getItems(),goSportsTeam=true;// badvari,items=getItems(),dragonball,goSportsTeam=true,len;// goodvaritems=getItems(),goSportsTeam=true,dragonball,length,i;
  • 변수의 할당은 스코프의 시작 부분에서 해주십시오. 이것은 변수 선언과 Hoisting 관련 문제를 해결합니다.

    // badfunction(){test();console.log('doing stuff..');//..other stuff..varname=getName();if(name==='test'){returnfalse;}returnname;}// goodfunction(){varname=getName();test();console.log('doing stuff..');//..other stuff..if(name==='test'){returnfalse;}returnname;}// badfunction(){varname=getName();if(!arguments.length){returnfalse;}returntrue;}// goodfunction(){if(!arguments.length){returnfalse;}varname=getName();returntrue;}

    [↑]

  • 해당 스코프의 시작 부분에 Hoist된 변수선언은 할당되지 않습니다.

    // (notDefined가 전역 변수에 존재하지 않는다고 가정했을 경우)// 이것은 동작하지 않습니다.functionexample(){console.log(notDefined);// => throws a ReferenceError}// 그 변수를 참조하는 코드 후에 그 변수를 선언 한 경우// 변수가 Hoist된 상태에서 작동합니다.// Note : `true`라는 값 자체는 Hoist되지 않습니다.functionexample(){console.log(declaredButNotAssigned);// => undefinedvardeclaredButNotAssigned=true;}// 인터 프린터는 변수 선언을 스코프의 시작 부분에 Hoist합니다.// 위의 예는 다음과 같이 다시 작성할 수 있습니다.functionexample(){vardeclaredButNotAssigned;console.log(declaredButNotAssigned);// => undefineddeclaredButNotAssigned=true;}
  • 익명 함수의 경우 함수가 할당되기 전에 변수가 Hoist될 수 있습니다.

    functionexample(){console.log(anonymous);// => undefinedanonymous();// => TypeError anonymous is not a functionvaranonymous=function(){console.log('anonymous function expression');};}
  • 명명 된 함수의 경우도 마찬가지로 변수가 Hoist될 수 있습니다. 함수 이름과 함수 본체는 Hoist되지 않습니다.

    functionexample(){console.log(named);// => undefinednamed();// => TypeError named is not a functionsuperPower();// => ReferenceError superPower is not definedvarnamed=functionsuperPower(){console.log('Flying');};}// 함수이름과 변수이름이 같은 경우에도 같은 일이 일어납니다.functionexample(){console.log(named);// => undefinednamed();// => TypeError named is not a functionvarnamed=functionnamed(){console.log('named');}}
  • 함수 선언은 함수이름과 함수본문이 Hoist됩니다.

    functionexample(){superPower();// => FlyingfunctionsuperPower(){console.log('Flying');}}
  • 더 자세한 정보는 Ben CherryJavaScript Scoping & Hoisting를 참조하십시오.

    [↑]

  • ==!= 보다는 ===!== 를 사용해 주십시오

  • 조건식은ToBoolean 메소드에 의해 엄밀하게 비교됩니다. 항상 이 간단한 규칙에 따라 주십시오.

    • Objectstrue 로 평가됩니다.
    • undefinedfalse 로 평가됩니다.
    • nullfalse 로 평가됩니다.
    • Booleansboolean형의 값 으로 평가됩니다.
    • Numberstrue 로 평가됩니다. 하지만 +0, -0, or NaN 의 경우는 false 입니다.
    • Stringstrue 로 평가됩니다. 하지만 빈문자 '' 의 경우는 false 입니다.
    if([0]){// true// Array는 Object 이므로 true 로 평가됩니다.}
  • 짧은형식을 사용하십시오.

    // badif(name!==''){// ...stuff...}// goodif(name){// ...stuff...}// badif(collection.length>0){// ...stuff...}// goodif(collection.length){// ...stuff...}
  • 더 자세한 정보는 Angus Croll 의 Truth Equality and JavaScript를 참고해 주십시오.

    [↑]

  • 복수행 블록은 중괄호 ({})를 사용하십시오.

    // badif(test)returnfalse;// goodif(test)returnfalse;// goodif(test){returnfalse;}// badfunction(){returnfalse;}// goodfunction(){returnfalse;}

    [↑]

  • 복수행의 코멘트는 /** ... */ 를 사용해 주십시오. 그 안에는 설명과 모든 매개 변수와 반환 값에 대한 형식과 값을 설명합니다.

    // bad// make() returns a new element// based on the passed in tag name//// @param <String> tag// @return <Element> elementfunctionmake(tag){// ...stuff...returnelement;}// good/** * make() returns a new element * based on the passed in tag name * * @param <String> tag * @return <Element> element */functionmake(tag){// ...stuff...returnelement;}
  • 한 줄 주석에는//를 사용하십시오. 코멘트를 추가하고 싶은 코드의 상단에 작성하십시오. 또한 주석 앞에 빈 줄을 넣어주십시오.

    // badvaractive=true;// is current tab// good// is current tabvaractive=true;// badfunctiongetType(){console.log('fetching type...');// set the default type to 'no type'vartype=this._type||'no type';returntype;}// goodfunctiongetType(){console.log('fetching type...');// set the default type to 'no type'vartype=this._type||'no type';returntype;}
  • 문제를 지적하고 재고를 촉구하거나 문제에 대한 해결책을 제시하는 등 의견의 앞에 FIXMETODO를 붙이는 것으로 다른 개발자의 빠른 이해를 도울 수 있습니다. 이러한 어떤 액션을 동반한다는 의미에서 일반 코멘트와는 다릅니다. 액션은 FIXME - 해결책이 필요 또는 TODO - 구현이 필요 입니다.

  • 문제에 대한 코멘트로 // FIXME :를 사용하십시오.

    functionCalculator(){// FIXME: 전역 변수를 사용해서는 안됩니다.total=0;returnthis;}
  • 문제 해결책에 대한 코멘트로 // TODO :를 사용하십시오.

    functionCalculator(){// TODO: total은 옵션 매개 변수로 설정되어야 함.this.total=0;returnthis;}

[↑]

  • 탭에는 공백 2개를 설정하십시오.

    // badfunction(){∙∙∙∙varname;}// badfunction(){∙varname;}// goodfunction(){∙∙varname;}
  • 중괄호({})의 앞에 공백을 하나 넣어주십시오.

    // badfunctiontest(){console.log('test');}// goodfunctiontest(){console.log('test');}// baddog.set('attr',{age: '1 year',breed: 'Bernese Mountain Dog'});// gooddog.set('attr',{age: '1 year',breed: 'Bernese Mountain Dog'});
  • 파일의 마지막에는 빈 줄을 하나 넣어주십시오.

    // bad(function(global){// ...stuff...})(this);
    // good(function(global){// ...stuff...})(this);
  • 메소드 체인이 길어지는 경우 적절히 들여쓰기(indentation) 하십시오.

    // bad$('#items').find('.selected').highlight().end().find('.open').updateCount();// good$('#items').find('.selected').highlight().end().find('.open').updateCount();// badvarleds=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);// goodvarleds=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);

    [↑]

  • 선두의 comma는 하지마십시오.

    // badvaronce,upon,aTime;// goodvaronce,upon,aTime;// badvarhero={firstName: 'Bob',lastName: 'Parr',heroName: 'Mr. Incredible',superPower: 'strength'};// goodvarhero={firstName: 'Bob',lastName: 'Parr',heroName: 'Mr. Incredible',superPower: 'strength'};
  • 말미의 불필요한 쉼표도 하지 마십시오. 이것은 IE6/7과 quirksmode의 IE9에서 문제를 일으킬 수 있습니다. 또한 ES3의 일부 구현에서 불필요한 쉼표가 있는 경우, 배열 길이를 추가합니다. 이것은 ES5에서 분명해졌습니다.(source):

    제 5 판에서는 말미의 불필요한 쉼표가 있는 ArrayInitialiser (배열 초기화 연산자)라도 배열에 길이를 추가하지 않는다는 사실을 명확히하고 있습니다. 이것은 제 3 판에서 의미적인 변경은 아닙니다만, 일부의 구현은 이전부터 이것을 오해하고 있었을지도 모릅니다.

    // badvarhero={firstName: 'Kevin',lastName: 'Flynn',};varheroes=['Batman','Superman',];// goodvarhero={firstName: 'Kevin',lastName: 'Flynn'};varheroes=['Batman','Superman'];

    [↑]

  • 네!(Yup.)

    // bad(function(){varname='Skywalker'returnname})()// good(function(){varname='Skywalker';returnname;})();// good;(function(){varname='Skywalker';returnname;})();

    [↑]

  • 문의 시작 부분에서 형을 강제합니다.

  • Strings:

    // => this.reviewScore = 9;// badvartotalScore=this.reviewScore+'';// goodvartotalScore=''+this.reviewScore;// badvartotalScore=''+this.reviewScore+' total score';// goodvartotalScore=this.reviewScore+' total score';
  • 숫자는parseInt를 사용하십시오. 항상 형변환을 위한 기수(radix)를 인수로 전달하십시오.

    varinputValue='4';// badvarval=newNumber(inputValue);// badvarval=+inputValue;// badvarval=inputValue>>0;// badvarval=parseInt(inputValue);// goodvarval=Number(inputValue);// goodvarval=parseInt(inputValue,10);
  • 어떤 이유에 의해 parseInt 가 병목이 되고, 성능적인 이유로 Bitshift를 사용할 필요가 있을 경우, 하려고 하는것에 대해, why(왜)와 what(무엇)의 설명을 코멘트로 남겨주십시오.

    // good/** * parseInt가 병목을 일으키므로 * Bitshift로 문자열을 수치로 강제적으로 변환하는 방법으로 * 성능을 개선시킵니다. */varval=inputValue>>0;
  • Booleans:

    varage=0;// badvarhasAge=newBoolean(age);// goodvarhasAge=Boolean(age);// goodvarhasAge=!!age;

    [↑]

  • 한문자 이름은 피하십시오. 이름에서 의도를 읽을 수 있도록 하십시오.

    // badfunctionq(){// ...stuff...}// goodfunctionquery(){// ..stuff..}
  • Object, 함수, 그리고 인스턴스로는 camelCase를 사용하십시오.

    // badvarOBJEcttsssss={};varthis_is_my_object={};varthis-is-my-object={};functionc(){};varu=newuser({name: 'Bob Parr'});// goodvarthisIsMyObject={};functionthisIsMyFunction(){};varuser=newUser({name: 'Bob Parr'});
  • Class와 생성자에는 PascalCase를 사용하십시오.

    // badfunctionuser(options){this.name=options.name;}varbad=newuser({name: 'nope'});// goodfunctionUser(options){this.name=options.name;}vargood=newUser({name: 'yup'});
  • private 속성 이름은 밑줄 _ 을 사용하십시오.

    // badthis.__firstName__='Panda';this.firstName_='Panda';// goodthis._firstName='Panda';
  • this의 참조를 저장할 때 _this 를 사용하십시오.

    // badfunction(){varself=this;returnfunction(){console.log(self);};}// badfunction(){varthat=this;returnfunction(){console.log(that);};}// goodfunction(){var_this=this;returnfunction(){console.log(_this);};}
  • 함수에 이름을 붙여주십시오. 이것은 stack traces를 추적하기 쉽게하기 때문입니다.

    // badvarlog=function(msg){console.log(msg);};// goodvarlog=functionlog(msg){console.log(msg);};

    [↑]

  • 속성을 위한 접근자(Accessor) 함수는 필요 없습니다.

  • 접근자 함수가 필요한 경우 getVal() 이나 setVal('hello') 라고 사용합니다.

    // baddragon.age();// gooddragon.getAge();// baddragon.age(25);// gooddragon.setAge(25);
  • 속성이 boolean의 경우 isVal() 이나 hasVal() 라고 사용합니다.

    // badif(!dragon.age()){returnfalse;}// goodif(!dragon.hasAge()){returnfalse;}
  • 일관된다면 get() 이나 set() 이라는 함수를 작성해도 좋습니다.

    functionJedi(options){options||(options={});varlightsaber=options.lightsaber||'blue';this.set('lightsaber',lightsaber);}Jedi.prototype.set=function(key,val){this[key]=val;};Jedi.prototype.get=function(key){returnthis[key];};

    [↑]

  • 새 Object에서 프로토타입을 재정의하는 것이 아니라, 프로토타입 객체에 메서드를 추가해 주십시오. 프로토타입을 재정의하면 상속이 불가능합니다. 프로토타입을 리셋하는것으로 베이스 클래스를 재정의 할 수 있습니다.

    functionJedi(){console.log('new jedi');}// badJedi.prototype={fight: functionfight(){console.log('fighting');},block: functionblock(){console.log('blocking');}};// goodJedi.prototype.fight=functionfight(){console.log('fighting');};Jedi.prototype.block=functionblock(){console.log('blocking');};
  • 메소드의 반환 값으로 this를 반환함으로써 메소드 체인을 할 수 있습니다.

    // badJedi.prototype.jump=function(){this.jumping=true;returntrue;};Jedi.prototype.setHeight=function(height){this.height=height;};varluke=newJedi();luke.jump();// => trueluke.setHeight(20)// => undefined// goodJedi.prototype.jump=function(){this.jumping=true;returnthis;};Jedi.prototype.setHeight=function(height){this.height=height;returnthis;};varluke=newJedi();luke.jump().setHeight(20);
  • 독자적인 toString()을 만들 수도 있지만 올바르게 작동하는지, 부작용이 없는 것만은 확인해 주십시오.

    functionJedi(options){options||(options={});this.name=options.name||'no name';}Jedi.prototype.getName=functiongetName(){returnthis.name;};Jedi.prototype.toString=functiontoString(){return'Jedi - '+this.getName();};

    [↑]

  • (DOM 이벤트나 Backbone events와 같은 고유의) 이벤트 탑재체(payloads)의 값을 전달하는 경우 원시 값(raw value) 대신 해시 인수(hash)를 전달합니다. 이렇게하는 것으로 나중에 개발자가 이벤트와 관련된 모든 핸들러를 찾아 업데이트 하지 않고 이벤트 탑재체(payloads)에 값을 추가 할 수 있습니다. 예를 들어, 이것 대신 :

    // bad$(this).trigger('listingUpdated',listing.id);
    ...
    $(this).on('listingUpdated',function(e,listingId){// do something with listingId});

    이쪽을 선호합니다.:

    // good$(this).trigger('listingUpdated',{listingId : listing.id});
    ...
    $(this).on('listingUpdated',function(e,data){// do something with data.listingId});

[↑]

  • 모듈의 시작은 ! 로 시작하십시오. 이것은 문말에 세미콜론을 넣는것을 잊은 모듈을 연결할때 런타임 오류가 발생하지 않기 때문입니다.

  • 파일 이름은 camelCase를 사용하여 같은 이름의 폴더에 저장해주십시오. 또한 단독으로 공개할 경우 이름을 일치시켜주십시오.

  • noConflict() 라는 명칭으로 (이름이 겹쳐 덮어 써지기 전의) 모듈을 반환하는 메서드를 추가해주십시오.

  • 항상 모듈의 시작 부분에서 'use strict';를 선언해주십시오.

    // fancyInput/fancyInput.js!function(global){'use strict';varpreviousFancyInput=global.FancyInput;functionFancyInput(options){this.options=options||{};}FancyInput.noConflict=functionnoConflict(){global.FancyInput=previousFancyInput;returnFancyInput;};global.FancyInput=FancyInput;}(this);

    [↑]

  • jQuery Object의 변수 앞에는 $을 부여해 주십시오.

    // badvarsidebar=$('.sidebar');// goodvar$sidebar=$('.sidebar');
  • jQuery 쿼리결과를 캐시해주십시오.

    // badfunctionsetSidebar(){$('.sidebar').hide();// ...stuff...$('.sidebar').css({'background-color': 'pink'});}// goodfunctionsetSidebar(){var$sidebar=$('.sidebar');$sidebar.hide();// ...stuff...$sidebar.css({'background-color': 'pink'});}
  • DOM 검색은 Cascading $('.sidebar ul') 이나 parent > child $('.sidebar > ul') 를 사용해주십시오. jsPerf

  • jQuery Object 검색은 스코프가 붙은 find를 사용해주십시오.

    // bad$('ul','.sidebar').hide();// bad$('.sidebar').find('ul').hide();// good$('.sidebar ul').hide();// good$('.sidebar > ul').hide();// good$sidebar.find('ul');

    [↑]

[↑]

  • 네!(Yup.)

    function(){returntrue;}

    [↑]

[↑]

Read This

Other Styleguides

Other Styles

Further Reading

Books

Blogs

[↑]

This is a list of organizations that are using this style guide. Send us a pull request or open an issue and we'll add you to the list.

This style guide is also available in other languages:

(The MIT License)

Copyright (c) 2012 Airbnb

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

[↑]

};

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); javascript-style-guide/es5.md at master · tipjs/javascript-style-guide · GitHub
Skip to content

Latest commit

History

History
1524 lines (1122 loc) · 39.4 KB

File metadata and controls

1524 lines (1122 loc) · 39.4 KB

원문:https://github.com/airbnb/javascript

Airbnb JavaScript 스타일 가이드() {

  1. Types
  2. Objects
  3. Arrays
  4. Strings
  5. Functions
  6. Properties
  7. Variables
  8. Hoisting
  9. Conditional Expressions & Equality
  10. Blocks
  11. Comments
  12. Whitespace
  13. Commas
  14. Semicolons
  15. Type Casting & Coercion
  16. Naming Conventions
  17. Accessors
  18. Constructors
  19. Events
  20. Modules
  21. jQuery
  22. ES5 Compatibility
  23. Testing
  24. Performance
  25. Resources
  26. In the Wild
  27. Translation
  28. The JavaScript Style Guide Guide
  29. Contributors
  30. License
  • Primitives: primitive type은 그 값을 직접 조작합니다.

    • string
    • number
    • boolean
    • null
    • undefined
    varfoo=1,bar=foo;bar=9;console.log(foo,bar);// => 1, 9
  • Complex: 참조형(Complex)은 참조를 통해 값을 조작합니다.

    • object
    • array
    • function
    varfoo=[1,2],bar=foo;bar[0]=9;console.log(foo[0],bar[0]);// => 9, 9

    [↑]

  • Object를 만들 때는 리터럴 구문을 사용하십시오.

    // badvaritem=newObject();// goodvaritem={};
  • 예약어(reserved words)를 키로 사용하지 마십시오. 이것은 IE8에서 동작하지 않습니다. More info

    // badvarsuperman={default: {clark: 'kent'},private: true};// goodvarsuperman={defaults: {clark: 'kent'},hidden: true};
  • 예약어 대신 알기 쉬운 동의어(readable synonyms)를 사용하십시오.

    // badvarsuperman={class: 'alien'};// badvarsuperman={klass: 'alien'};// goodvarsuperman={type: 'alien'};

    [↑]

  • 배열을 만들 때 리터럴 구문을 사용하십시오.

    // badvaritems=newArray();// goodvaritems=[];
  • 길이를 알 수없는 경우는 Array#push를 사용하십시오.

    varsomeStack=[];// badsomeStack[someStack.length]='abracadabra';// goodsomeStack.push('abracadabra');
  • 배열을 복사 할 필요가있는 경우 Array#slice를 사용하십시오. jsPerf

    varlen=items.length,itemsCopy=[],i;// badfor(i=0;i<len;i++){itemsCopy[i]=items[i];}// gooditemsCopy=items.slice();
  • Array와 비슷한(Array-Like)한 Object를 Array에 변환하는 경우는 Array#slice를 사용하십시오.

    functiontrigger(){varargs=Array.prototype.slice.call(arguments);
    ...
    }

[↑]

  • 문자열은 작은 따옴표''를 사용하십시오.

    // badvarname="Bob Parr";// goodvarname='Bob Parr';// badvarfullName="Bob "+this.lastName;// goodvarfullName='Bob '+this.lastName;
  • 80 문자 이상의 문자열은 문자열 연결을 사용하여 여러 줄에 걸쳐 기술 할 필요가 있습니다.

  • Note : 문자열 연결을 많이하면 성능에 영향을 줄 수 있습니다. jsPerf & Discussion

    // badvarerrorMessage='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.';// badvarerrorMessage='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.';// goodvarerrorMessage='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.';
  • 프로그램에서 문자열을 생성 할 필요가 있는 경우 (특히 IE는) 문자열 연결 대신 Array#join을 사용하십시오. 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;// badfunctioninbox(messages){items='<ul>';for(i=0;i<length;i++){items+='<li>'+messages[i].message+'</li>';}returnitems+'</ul>';}// goodfunctioninbox(messages){items=[];for(i=0;i<length;i++){items[i]=messages[i].message;}return'<ul><li>'+items.join('</li><li>')+'</li></ul>';}

    [↑]

  • 함수식(Function expressions)

    // 익명함수식(anonymous function expression)varanonymous=function(){returntrue;};// 명명된 함수식(named function expression)varnamed=functionnamed(){returntrue;};// 즉시실행 함수식(immediately-invoked function expression (IIFE))(function(){console.log('Welcome to the Internet. Please follow me.');})();
  • (if 및 while 등) 블록 내에서 변수에 함수를 할당하는 대신 함수를 선언하지 마십시오. 브라우저는 허용하지만 (마치 'bad news bears'처럼) 모두 다른 방식으로 해석됩니다.

  • Note: ECMA-262에서는block은 statements의 목록에 정의되어 있습니다 만, 함수 선언은 statements가 없습니다. 이 문제는 ECMA-262의 설명을 참조하십시오. .

    // badif(currentUser){functiontest(){console.log('Nope.');}}// goodvartest;if(currentUser){test=functiontest(){console.log('Yup.');};}
  • 매개 변수(parameter)에 arguments를 절대 지정하지 마십시오. 이것은 함수 범위로 전달 될arguments객체의 참조를 덮어 쓸 것입니다.

    // badfunctionnope(name,options,arguments){// ...stuff...}// goodfunctionyup(name,options,args){// ...stuff...}

    [↑]

  • 속성에 액세스하려면 도트.를 사용하십시오.

    varluke={jedi: true,age: 28};// badvarisJedi=luke['jedi'];// goodvarisJedi=luke.jedi;
  • 변수를 사용하여 속성에 접근하려면 대괄호[]을 사용하십시오.

    varluke={jedi: true,age: 28};functiongetProp(prop){returnluke[prop];}varisJedi=getProp('jedi');

    [↑]

  • 변수를 선언 할 때는 항상 var를 사용하십시오. 그렇지 않으면 전역 변수로 선언됩니다. 전역 네임 스페이스를 오염시키지 않도록 Captain Planet도 경고하고 있습니다.

    // badsuperPower=newSuperPower();// goodvarsuperPower=newSuperPower();
  • 여러 변수를 선언하려면 하나의 var를 사용하여 변수마다 줄바꿈하여 선언하십시오.

    // badvaritems=getItems();vargoSportsTeam=true;vardragonball='z';// goodvaritems=getItems(),goSportsTeam=true,dragonball='z';
  • 정의되지 않은 변수를 마지막으로 선언하십시오. 이것은 나중에 이미 할당된 변수 중 하나를 지정해야하는 경우에 유용합니다.

    // badvari,len,dragonball,items=getItems(),goSportsTeam=true;// badvari,items=getItems(),dragonball,goSportsTeam=true,len;// goodvaritems=getItems(),goSportsTeam=true,dragonball,length,i;
  • 변수의 할당은 스코프의 시작 부분에서 해주십시오. 이것은 변수 선언과 Hoisting 관련 문제를 해결합니다.

    // badfunction(){test();console.log('doing stuff..');//..other stuff..varname=getName();if(name==='test'){returnfalse;}returnname;}// goodfunction(){varname=getName();test();console.log('doing stuff..');//..other stuff..if(name==='test'){returnfalse;}returnname;}// badfunction(){varname=getName();if(!arguments.length){returnfalse;}returntrue;}// goodfunction(){if(!arguments.length){returnfalse;}varname=getName();returntrue;}

    [↑]

  • 해당 스코프의 시작 부분에 Hoist된 변수선언은 할당되지 않습니다.

    // (notDefined가 전역 변수에 존재하지 않는다고 가정했을 경우)// 이것은 동작하지 않습니다.functionexample(){console.log(notDefined);// => throws a ReferenceError}// 그 변수를 참조하는 코드 후에 그 변수를 선언 한 경우// 변수가 Hoist된 상태에서 작동합니다.// Note : `true`라는 값 자체는 Hoist되지 않습니다.functionexample(){console.log(declaredButNotAssigned);// => undefinedvardeclaredButNotAssigned=true;}// 인터 프린터는 변수 선언을 스코프의 시작 부분에 Hoist합니다.// 위의 예는 다음과 같이 다시 작성할 수 있습니다.functionexample(){vardeclaredButNotAssigned;console.log(declaredButNotAssigned);// => undefineddeclaredButNotAssigned=true;}
  • 익명 함수의 경우 함수가 할당되기 전에 변수가 Hoist될 수 있습니다.

    functionexample(){console.log(anonymous);// => undefinedanonymous();// => TypeError anonymous is not a functionvaranonymous=function(){console.log('anonymous function expression');};}
  • 명명 된 함수의 경우도 마찬가지로 변수가 Hoist될 수 있습니다. 함수 이름과 함수 본체는 Hoist되지 않습니다.

    functionexample(){console.log(named);// => undefinednamed();// => TypeError named is not a functionsuperPower();// => ReferenceError superPower is not definedvarnamed=functionsuperPower(){console.log('Flying');};}// 함수이름과 변수이름이 같은 경우에도 같은 일이 일어납니다.functionexample(){console.log(named);// => undefinednamed();// => TypeError named is not a functionvarnamed=functionnamed(){console.log('named');}}
  • 함수 선언은 함수이름과 함수본문이 Hoist됩니다.

    functionexample(){superPower();// => FlyingfunctionsuperPower(){console.log('Flying');}}
  • 더 자세한 정보는 Ben CherryJavaScript Scoping & Hoisting를 참조하십시오.

    [↑]

  • ==!= 보다는 ===!== 를 사용해 주십시오

  • 조건식은ToBoolean 메소드에 의해 엄밀하게 비교됩니다. 항상 이 간단한 규칙에 따라 주십시오.

    • Objectstrue 로 평가됩니다.
    • undefinedfalse 로 평가됩니다.
    • nullfalse 로 평가됩니다.
    • Booleansboolean형의 값 으로 평가됩니다.
    • Numberstrue 로 평가됩니다. 하지만 +0, -0, or NaN 의 경우는 false 입니다.
    • Stringstrue 로 평가됩니다. 하지만 빈문자 '' 의 경우는 false 입니다.
    if([0]){// true// Array는 Object 이므로 true 로 평가됩니다.}
  • 짧은형식을 사용하십시오.

    // badif(name!==''){// ...stuff...}// goodif(name){// ...stuff...}// badif(collection.length>0){// ...stuff...}// goodif(collection.length){// ...stuff...}
  • 더 자세한 정보는 Angus Croll 의 Truth Equality and JavaScript를 참고해 주십시오.

    [↑]

  • 복수행 블록은 중괄호 ({})를 사용하십시오.

    // badif(test)returnfalse;// goodif(test)returnfalse;// goodif(test){returnfalse;}// badfunction(){returnfalse;}// goodfunction(){returnfalse;}

    [↑]

  • 복수행의 코멘트는 /** ... */ 를 사용해 주십시오. 그 안에는 설명과 모든 매개 변수와 반환 값에 대한 형식과 값을 설명합니다.

    // bad// make() returns a new element// based on the passed in tag name//// @param <String> tag// @return <Element> elementfunctionmake(tag){// ...stuff...returnelement;}// good/** * make() returns a new element * based on the passed in tag name * * @param <String> tag * @return <Element> element */functionmake(tag){// ...stuff...returnelement;}
  • 한 줄 주석에는//를 사용하십시오. 코멘트를 추가하고 싶은 코드의 상단에 작성하십시오. 또한 주석 앞에 빈 줄을 넣어주십시오.

    // badvaractive=true;// is current tab// good// is current tabvaractive=true;// badfunctiongetType(){console.log('fetching type...');// set the default type to 'no type'vartype=this._type||'no type';returntype;}// goodfunctiongetType(){console.log('fetching type...');// set the default type to 'no type'vartype=this._type||'no type';returntype;}
  • 문제를 지적하고 재고를 촉구하거나 문제에 대한 해결책을 제시하는 등 의견의 앞에 FIXMETODO를 붙이는 것으로 다른 개발자의 빠른 이해를 도울 수 있습니다. 이러한 어떤 액션을 동반한다는 의미에서 일반 코멘트와는 다릅니다. 액션은 FIXME - 해결책이 필요 또는 TODO - 구현이 필요 입니다.

  • 문제에 대한 코멘트로 // FIXME :를 사용하십시오.

    functionCalculator(){// FIXME: 전역 변수를 사용해서는 안됩니다.total=0;returnthis;}
  • 문제 해결책에 대한 코멘트로 // TODO :를 사용하십시오.

    functionCalculator(){// TODO: total은 옵션 매개 변수로 설정되어야 함.this.total=0;returnthis;}

[↑]

  • 탭에는 공백 2개를 설정하십시오.

    // badfunction(){∙∙∙∙varname;}// badfunction(){∙varname;}// goodfunction(){∙∙varname;}
  • 중괄호({})의 앞에 공백을 하나 넣어주십시오.

    // badfunctiontest(){console.log('test');}// goodfunctiontest(){console.log('test');}// baddog.set('attr',{age: '1 year',breed: 'Bernese Mountain Dog'});// gooddog.set('attr',{age: '1 year',breed: 'Bernese Mountain Dog'});
  • 파일의 마지막에는 빈 줄을 하나 넣어주십시오.

    // bad(function(global){// ...stuff...})(this);
    // good(function(global){// ...stuff...})(this);
  • 메소드 체인이 길어지는 경우 적절히 들여쓰기(indentation) 하십시오.

    // bad$('#items').find('.selected').highlight().end().find('.open').updateCount();// good$('#items').find('.selected').highlight().end().find('.open').updateCount();// badvarleds=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);// goodvarleds=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);

    [↑]

  • 선두의 comma는 하지마십시오.

    // badvaronce,upon,aTime;// goodvaronce,upon,aTime;// badvarhero={firstName: 'Bob',lastName: 'Parr',heroName: 'Mr. Incredible',superPower: 'strength'};// goodvarhero={firstName: 'Bob',lastName: 'Parr',heroName: 'Mr. Incredible',superPower: 'strength'};
  • 말미의 불필요한 쉼표도 하지 마십시오. 이것은 IE6/7과 quirksmode의 IE9에서 문제를 일으킬 수 있습니다. 또한 ES3의 일부 구현에서 불필요한 쉼표가 있는 경우, 배열 길이를 추가합니다. 이것은 ES5에서 분명해졌습니다.(source):

    제 5 판에서는 말미의 불필요한 쉼표가 있는 ArrayInitialiser (배열 초기화 연산자)라도 배열에 길이를 추가하지 않는다는 사실을 명확히하고 있습니다. 이것은 제 3 판에서 의미적인 변경은 아닙니다만, 일부의 구현은 이전부터 이것을 오해하고 있었을지도 모릅니다.

    // badvarhero={firstName: 'Kevin',lastName: 'Flynn',};varheroes=['Batman','Superman',];// goodvarhero={firstName: 'Kevin',lastName: 'Flynn'};varheroes=['Batman','Superman'];

    [↑]

  • 네!(Yup.)

    // bad(function(){varname='Skywalker'returnname})()// good(function(){varname='Skywalker';returnname;})();// good;(function(){varname='Skywalker';returnname;})();

    [↑]

  • 문의 시작 부분에서 형을 강제합니다.

  • Strings:

    // => this.reviewScore = 9;// badvartotalScore=this.reviewScore+'';// goodvartotalScore=''+this.reviewScore;// badvartotalScore=''+this.reviewScore+' total score';// goodvartotalScore=this.reviewScore+' total score';
  • 숫자는parseInt를 사용하십시오. 항상 형변환을 위한 기수(radix)를 인수로 전달하십시오.

    varinputValue='4';// badvarval=newNumber(inputValue);// badvarval=+inputValue;// badvarval=inputValue>>0;// badvarval=parseInt(inputValue);// goodvarval=Number(inputValue);// goodvarval=parseInt(inputValue,10);
  • 어떤 이유에 의해 parseInt 가 병목이 되고, 성능적인 이유로 Bitshift를 사용할 필요가 있을 경우, 하려고 하는것에 대해, why(왜)와 what(무엇)의 설명을 코멘트로 남겨주십시오.

    // good/** * parseInt가 병목을 일으키므로 * Bitshift로 문자열을 수치로 강제적으로 변환하는 방법으로 * 성능을 개선시킵니다. */varval=inputValue>>0;
  • Booleans:

    varage=0;// badvarhasAge=newBoolean(age);// goodvarhasAge=Boolean(age);// goodvarhasAge=!!age;

    [↑]

  • 한문자 이름은 피하십시오. 이름에서 의도를 읽을 수 있도록 하십시오.

    // badfunctionq(){// ...stuff...}// goodfunctionquery(){// ..stuff..}
  • Object, 함수, 그리고 인스턴스로는 camelCase를 사용하십시오.

    // badvarOBJEcttsssss={};varthis_is_my_object={};varthis-is-my-object={};functionc(){};varu=newuser({name: 'Bob Parr'});// goodvarthisIsMyObject={};functionthisIsMyFunction(){};varuser=newUser({name: 'Bob Parr'});
  • Class와 생성자에는 PascalCase를 사용하십시오.

    // badfunctionuser(options){this.name=options.name;}varbad=newuser({name: 'nope'});// goodfunctionUser(options){this.name=options.name;}vargood=newUser({name: 'yup'});
  • private 속성 이름은 밑줄 _ 을 사용하십시오.

    // badthis.__firstName__='Panda';this.firstName_='Panda';// goodthis._firstName='Panda';
  • this의 참조를 저장할 때 _this 를 사용하십시오.

    // badfunction(){varself=this;returnfunction(){console.log(self);};}// badfunction(){varthat=this;returnfunction(){console.log(that);};}// goodfunction(){var_this=this;returnfunction(){console.log(_this);};}
  • 함수에 이름을 붙여주십시오. 이것은 stack traces를 추적하기 쉽게하기 때문입니다.

    // badvarlog=function(msg){console.log(msg);};// goodvarlog=functionlog(msg){console.log(msg);};

    [↑]

  • 속성을 위한 접근자(Accessor) 함수는 필요 없습니다.

  • 접근자 함수가 필요한 경우 getVal() 이나 setVal('hello') 라고 사용합니다.

    // baddragon.age();// gooddragon.getAge();// baddragon.age(25);// gooddragon.setAge(25);
  • 속성이 boolean의 경우 isVal() 이나 hasVal() 라고 사용합니다.

    // badif(!dragon.age()){returnfalse;}// goodif(!dragon.hasAge()){returnfalse;}
  • 일관된다면 get() 이나 set() 이라는 함수를 작성해도 좋습니다.

    functionJedi(options){options||(options={});varlightsaber=options.lightsaber||'blue';this.set('lightsaber',lightsaber);}Jedi.prototype.set=function(key,val){this[key]=val;};Jedi.prototype.get=function(key){returnthis[key];};

    [↑]

  • 새 Object에서 프로토타입을 재정의하는 것이 아니라, 프로토타입 객체에 메서드를 추가해 주십시오. 프로토타입을 재정의하면 상속이 불가능합니다. 프로토타입을 리셋하는것으로 베이스 클래스를 재정의 할 수 있습니다.

    functionJedi(){console.log('new jedi');}// badJedi.prototype={fight: functionfight(){console.log('fighting');},block: functionblock(){console.log('blocking');}};// goodJedi.prototype.fight=functionfight(){console.log('fighting');};Jedi.prototype.block=functionblock(){console.log('blocking');};
  • 메소드의 반환 값으로 this를 반환함으로써 메소드 체인을 할 수 있습니다.

    // badJedi.prototype.jump=function(){this.jumping=true;returntrue;};Jedi.prototype.setHeight=function(height){this.height=height;};varluke=newJedi();luke.jump();// => trueluke.setHeight(20)// => undefined// goodJedi.prototype.jump=function(){this.jumping=true;returnthis;};Jedi.prototype.setHeight=function(height){this.height=height;returnthis;};varluke=newJedi();luke.jump().setHeight(20);
  • 독자적인 toString()을 만들 수도 있지만 올바르게 작동하는지, 부작용이 없는 것만은 확인해 주십시오.

    functionJedi(options){options||(options={});this.name=options.name||'no name';}Jedi.prototype.getName=functiongetName(){returnthis.name;};Jedi.prototype.toString=functiontoString(){return'Jedi - '+this.getName();};

    [↑]

  • (DOM 이벤트나 Backbone events와 같은 고유의) 이벤트 탑재체(payloads)의 값을 전달하는 경우 원시 값(raw value) 대신 해시 인수(hash)를 전달합니다. 이렇게하는 것으로 나중에 개발자가 이벤트와 관련된 모든 핸들러를 찾아 업데이트 하지 않고 이벤트 탑재체(payloads)에 값을 추가 할 수 있습니다. 예를 들어, 이것 대신 :

    // bad$(this).trigger('listingUpdated',listing.id);
    ...
    $(this).on('listingUpdated',function(e,listingId){// do something with listingId});

    이쪽을 선호합니다.:

    // good$(this).trigger('listingUpdated',{listingId : listing.id});
    ...
    $(this).on('listingUpdated',function(e,data){// do something with data.listingId});

[↑]

  • 모듈의 시작은 ! 로 시작하십시오. 이것은 문말에 세미콜론을 넣는것을 잊은 모듈을 연결할때 런타임 오류가 발생하지 않기 때문입니다.

  • 파일 이름은 camelCase를 사용하여 같은 이름의 폴더에 저장해주십시오. 또한 단독으로 공개할 경우 이름을 일치시켜주십시오.

  • noConflict() 라는 명칭으로 (이름이 겹쳐 덮어 써지기 전의) 모듈을 반환하는 메서드를 추가해주십시오.

  • 항상 모듈의 시작 부분에서 'use strict';를 선언해주십시오.

    // fancyInput/fancyInput.js!function(global){'use strict';varpreviousFancyInput=global.FancyInput;functionFancyInput(options){this.options=options||{};}FancyInput.noConflict=functionnoConflict(){global.FancyInput=previousFancyInput;returnFancyInput;};global.FancyInput=FancyInput;}(this);

    [↑]

  • jQuery Object의 변수 앞에는 $을 부여해 주십시오.

    // badvarsidebar=$('.sidebar');// goodvar$sidebar=$('.sidebar');
  • jQuery 쿼리결과를 캐시해주십시오.

    // badfunctionsetSidebar(){$('.sidebar').hide();// ...stuff...$('.sidebar').css({'background-color': 'pink'});}// goodfunctionsetSidebar(){var$sidebar=$('.sidebar');$sidebar.hide();// ...stuff...$sidebar.css({'background-color': 'pink'});}
  • DOM 검색은 Cascading $('.sidebar ul') 이나 parent > child $('.sidebar > ul') 를 사용해주십시오. jsPerf

  • jQuery Object 검색은 스코프가 붙은 find를 사용해주십시오.

    // bad$('ul','.sidebar').hide();// bad$('.sidebar').find('ul').hide();// good$('.sidebar ul').hide();// good$('.sidebar > ul').hide();// good$sidebar.find('ul');

    [↑]

[↑]

  • 네!(Yup.)

    function(){returntrue;}

    [↑]

[↑]

Read This

Other Styleguides

Other Styles

Further Reading

Books

Blogs

[↑]

This is a list of organizations that are using this style guide. Send us a pull request or open an issue and we'll add you to the list.

This style guide is also available in other languages:

(The MIT License)

Copyright (c) 2012 Airbnb

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

[↑]

};