프로젝트를 위해 선택한 스타일은 최고 기준이어야합니다. 프로젝트에 설명으로 배치하고 코드 스타일 일관성, 가독성 및 유지 관리를 보장하기 위해이 문서에 연결하십시오.
1. 공백
1. 공간과 탭을 섞지 마십시오.
2. 프로젝트를 시작하고 코드를 작성하기 전에 소프트 indent (공간) 또는 탭 (들여 쓰기 방법)을 선택하고 가장 높은 기준으로 사용하십시오.
에이). 가독성을 위해 편집에서 2 개의 문자 너비 압입을 항상 설계하는 것이 좋습니다. 이것은 탭 대신 두 개의 공간 또는 두 개의 공간에 해당합니다.
3. 편집기가 지원하는 경우 항상 "보이지 않는 문자 표시"설정을 켜십시오. 이점은 다음과 같습니다.
에이). 일관성을 보장하십시오
비). 선 끝의 공간을 제거하십시오
기음). 빈 공간을 제거하십시오
디). 제출 및 비교는 더 읽기 쉬운 것입니다
2. 문법을 아름답게합니다
A. 교정기, 교정기, 선 파손
코드 사본은 다음과 같습니다.
// if/else/for/while/try는 보통 버팀대, 곱슬 괄호 및 여러 줄이 있습니다.
// 이것은 읽기에 도움이됩니다
// 2.A.1.1
// 어려운 구문의 예
if (조건) dosomething ();
(조건) 반복 ++;
for (var i = 0; i <100; i ++) someTerativeFn ();
// 2.A.1.1
// 공백을 사용하여 가독성을 향상시킵니다
if (조건) {
// 성명
}
while (조건) {
// 성명
}
for (var i = 0; i <100; i ++) {
// 성명
}
// 더 나은 연습 :
var i,
길이 = 100;
for (i = 0; i <길이; i ++) {
// 성명
}
// 또는...
var i = 0,
길이 = 100;
for (; i <length; i ++) {
// 성명
}
var prop;
for (객체의 소품) {
// 성명
}
if (true) {
// 성명
} 또 다른 {
// 성명
}
B. 할당, 선언, 기능 (함수, 함수 표현식, 생성자 함수)
코드 사본은 다음과 같습니다.
// 2.B.1.1
// 변수
var foo = "bar",
num = 1,
undef;
// 문자 식별 :
var array = [],
객체 = {};
// 2.B.1.2
// 범위 내에서 하나의`var '만 사용하면 (함수) 가독성 향상에 도움이됩니다.
// 명세서 목록을 순서대로 만드십시오 (또한 몇 가지 키보드 타이핑을 저장합니다)
// 좋지 않습니다
var foo = "";
var bar = "";
var qux;
// 좋은
var foo = "",
bar = "",
Quux;
// 또는..
var //이 변수에 대한 주석
foo = "" ",
bar = "",
Quux;
// 2.B.1.3
//`var '문은 항상 각 범위 (함수)의 맨 위에 있어야합니다.
// ecmascript 6의 상수에도 적합합니다
// 좋지 않습니다
함수 foo () {
// 변수 앞에 문이 있습니다
var bar = "" ",
qux;
}
// 좋은
함수 foo () {
var bar = "" ",
qux;
// 모든 진술은 변수 뒤에 있습니다
}
// 2.B.2.1
// 이름이 함수 선언입니다
기능 foo (arg1, argn) {
}
// 사용 방법
foo (Arg1, argn);
// 2.B.2.2
// 이름이 함수 선언입니다
기능 제곱 (번호) {
반품 번호 * 번호;
}
// 사용 방법
제곱 (10);
// 매우 부 자연스러운 연속 통과 스타일
기능 제곱 (번호, 콜백) {
콜백 (번호 * 번호);
}
정사각형 (10, 함수 (Square) {
// 콜백 컨텐츠
});
// 2.B.2.3
// 함수 표현식
var square = function (number) {
// 귀중하고 관련 컨텐츠를 반환합니다
반품 번호 * 번호;
};
// 식별자가있는 함수 표현식
//이 선호하는 양식에는 스스로 호출 할 수있는 추가 기능이 있습니다.
// 스택에 식별자가 있습니다
var factorial = function factorial (번호) {
if (번호 <2) {
반환 1;
}
반품 번호 * factorial (number-1);
};
// 2.B.2.4
// 생성자 선언
기능 foobar (옵션) {
this.options = 옵션;
}
// 사용 방법
var foobar = new foobar ({a : "alpha"});
foobar.options;
// {A : "알파"}
C. 예외, 세부 사항
코드 사본은 다음과 같습니다.
// 2.C.1.1
// 콜백과 기능합니다
foo (function () {
// 참고 : 괄호 안에 공백이없고 첫 번째 함수 호출의 '기능'이 없습니다.
});
// 함수는`array '를 인수로 받아 공간이없는 인수로 받아들입니다.
foo ([ "알파", "베타"]);
// 2.C.1.2
// 함수는`객체 '를 공백없이 인수로 받아들입니다.
foo ({
A : "알파",
B : "베타"
});
// 함수는`string` 문자를 공백없이 인수로 받아들입니다.
foo ( "bar");
// 그룹화에 사용되는 괄호 안에는 공백이 없습니다.
if (! ( "foo"in obj)) {
}
D. 일관성은 항상 승리합니다
섹션 2.A-2.C에서, 빈 공간은 단순하고 높은 목적 인 통일에 기초하여 권장 방법으로 제안된다. "내부 공백 공간"과 같은 서식 기본 설정은 선택 사항이어야하지만 전체 프로젝트의 소스 코드는 하나만 있어야합니다.
코드 사본은 다음과 같습니다.
// 2.D.1.1
if (조건) {
// 성명
}
while (조건) {
// 성명
}
for (var i = 0; i <100; i ++) {
// 성명
}
if (true) {
// 성명
} 또 다른 {
// 성명
}
E. 견적 마크
단일 또는 이중 인용문을 선택하든 상관없이 JavaScript에서 구문 분석 차이를 만들지 않습니다. 절대적으로 의무화해야 할 것은 일관성입니다. 같은 프로젝트에서 두 개의 따옴표를 혼합하지 말고 하나를 선택하고 일관성을 유지하십시오.
F. 선 끝과 빈 줄
공백을 남기면 차이가 깨지고 사용 변경이 읽을 수 없습니다. 선의 끝에서 공간을 자동으로 삭제하는 사전 커밋 된 후크를 포함하는 것을 고려하십시오.
3. 유형 감지 (jQuery Core 스타일 지침)
A. 직접 유형 (실제 유형, 실제 유형)
끈:
코드 사본은 다음과 같습니다.
변수 타입 === "문자열"
숫자:
코드 사본은 다음과 같습니다.
변수 타입 === "숫자"
부울 :
코드 사본은 다음과 같습니다.
변수 타입 === "부울"
물체:
코드 사본은 다음과 같습니다.
변수 타입 === "객체"
정렬:
코드 사본은 다음과 같습니다.
Array.isArray (Array -LikeObject)
(가능하다면)
마디:
코드 사본은 다음과 같습니다.
elem.nodeType === 1
널 :
코드 사본은 다음과 같습니다.
변수 === null
널 또는 정의되지 않은 :
코드 사본은 다음과 같습니다.
변수 == null
한정되지 않은:
글로벌 변수 :
코드 사본은 다음과 같습니다.
변수 타입 === "정의되지 않은"
로컬 변수 :
코드 사본은 다음과 같습니다.
변수 === 정의되지 않았습니다
재산:
코드 사본은 다음과 같습니다.
object.prop === 정의되지 않았습니다
object.hasownproperty (prop)
물체에 "소품"
B. 변환 유형 (강제 유형, 강제 유형)
다음의 의미를 고려하십시오 ...
주어진 HTML :
코드 사본은 다음과 같습니다.
<입력 유형 = "text"id = "foo-input"value = "1">
// 3.B.1.1
//`foo`는`0`,`숫자 '를 입력했습니다.
var foo = 0;
// foo 타입;
// "숫자"
...
// 후속 코드에서는 'foo`를 업데이트하고 입력 요소에 얻은 새 값을 할당해야합니다.
foo = document.getElementById ( "foo-input"). 값;
//`foof 'type now를 테스트하면 결과는`string'입니다.
// 이것은 if 문서에서 'foo'를 감지 할 때 이와 유사한 논리가 있음을 의미합니다.
if (foo === 1) {
중요task ();
}
//`fooltask ()``foo '가 "1"의 값이 있더라도 실행되지 않습니다.
// 3.B.1.2
// +/- 단지 연산자를 영리하게 사용하여 유형을 시전하여 문제를 해결할 수 있습니다.
foo = +document.getElementById ( "foo-input"). 값;
// ^ + 단행 연산자는 작동 객체를 오른쪽으로`숫자 '로 변환합니다.
// foo 타입;
// "숫자"
if (foo === 1) {
중요task ();
}
//`extiumTask ()`가 호출됩니다
캐스팅을위한 몇 가지 예는 다음과 같습니다.
코드 사본은 다음과 같습니다.
// 3.B.2.1
var 번호 = 1,
문자열 = "1",
bool = false;
숫자;
// 1
번호 + "";
// "1"
끈;
// "1"
+문자열;
// 1
+문자열 ++;
// 1
끈;
// 2
부;
// 거짓
+bool;
// 0
bool + "";
// "거짓"
// 3.B.2.2
var 번호 = 1,
문자열 = "1",
bool = true;
문자열 === 숫자;
// 거짓
문자열 === 번호 + "";
// 진실
+문자열 === 숫자;
// 진실
bool === 숫자;
// 거짓
+bool === 숫자;
// 진실
bool === 문자열;
// 거짓
bool === !! 문자열;
// 진실
// 3.B.2.3
var array = [ "a", "b", "c"];
!! ~ array.indexof ( "a");
// 진실
!! ~ array.indexof ( "b");
// 진실
!! ~ array.indexof ( "c");
// 진실
!! ~ array.indexof ( "d");
// 거짓
// 위의 모든 것이 "불필요한 영리"라는 점에 주목할 가치가 있습니다.
// 명확한 체계를 사용하여 반환 된 값을 비교합니다.
// 예를 들면 Indexof :
if (array.indexof ( "a")> = 0) {
// ...
}
// 3.B.2.3
var num = 2.5;
parseint (Num, 10);
// 동등한 ...
~~ num;
num >> 0;
num >>> 0;
// 결과는 모두 2입니다
// 항상 명심하십시오. 음수 값은 다르게 취급됩니다 ...
var neg = -2.5;
parseint (Neg, 10);
// 동등한 ...
~~ 부정;
neg >> 0;
// 결과는 모두 -2입니다
// 하지만...
neg >>> 0;
// 결과는 4294967294입니다
4. 비교 작업
코드 사본은 다음과 같습니다.
// 4.1.1
// 배열이 길이가 있는지 여부를 판단 할 때 다음과 관련하여 다음과 같습니다.
if (array.length> 0) ...
// ... 진위를 결정하려면 다음을 사용하십시오.
if (array.length) ...
// 4.1.2
// 배열이 비어 있는지 판단 할 때는 이것을 사용하는 것과 관련하여 다음과 같습니다.
if (array.length === 0) ...
// ... 진위를 결정하려면 다음을 사용하십시오.
if (! array.length) ...
// 4.1.3
// 문자열이 비어 있는지 판단 할 때는 이것을 사용하는 것과 관련하여 다음과 같습니다.
if (string! == "") ...
// ... 진위를 결정하려면 다음을 사용하십시오.
if (string) ...
// 4.1.4
// 문자열이 비어 있다고 판단 할 때는 다음과 비교하여 다음과 같습니다.
if (string === "") ...
// ... 진위를 결정하려면 다음을 사용하십시오.
if (! string) ...
// 4.1.5
// 참조가 사실이라고 판단 할 때, 이것을 사용하는 것과 관련하여 :
if (foo === true) ...
// ... 당신이 생각하는 것처럼 판사, 내장 기능의 이점을 누리십시오.
if (foo) ...
// 4.1.6
// 참조가 거짓이라고 판단 할 때, 이것을 사용하는 것과 관련하여 :
if (foo === false) ...
// ... 느낌표를 사용하여 true로 변환합니다
if (! foo) ...
// ... 이것이 0, "", null, undefined, nan과 일치한다는 점에 유의해야합니다.
// _MUST_가 부울 유형 인 경우 다음을 사용하십시오.
if (foo === false) ...
// 4.1.7
// 참조를 계산하려면 NULL이거나 정의되지 않았지만 False가 아닙니다. ""또는 0,
//이 사용과 관련하여 :
if (foo === null || foo === 정의되지 않은) ...
// ... 다음과 같이 == 유형 주조의 이점을 누리십시오.
if (foo == null) ...
// 사용 == 사용은`null '일치`null'과`undefined '가됩니다.
//`false`, ""또는 0은 아닙니다
null == 정의되지 않았습니다
항상 가장 정확하고 정확한 가치를 판단하십시오. 위는 교리가 아닌 가이드입니다.
코드 사본은 다음과 같습니다.
// 4.2.1
// 유형 변환 및 비교 작업에 대한 지침
// 처음`===`,`==`따르는 (느슨한 유형 비교가 필요하지 않은 한)
//`===`항상 변환을 유형하는 것은 아닙니다. 즉, 다음을 의미합니다.
"1"=== 1;
// 거짓
//`==`유형을 변환합니다. 이는 다음을 의미합니다.
"1"== 1;
// 진실
// 4.2.2
// 부울, 진실 및 가짜
// 부울 :
사실, 거짓
// 진짜:
"foo", 1
// 의사 :
"", 0, null, null, nan, void 0
5. 실용적인 스타일
코드 사본은 다음과 같습니다.
// 5.1.1
// 실제 모듈
(기능 (글로벌) {
var module = (function () {
var data = "Secret";
반품 {
// 이것은 부울 가치입니다
bool : 사실,
// 문자열
문자열 : "문자열",
// 배열
배열 : [1, 2, 3, 4],
// 객체
물체: {
랭 : "en-us"
},
getData : function () {
//`data '의 값을 얻습니다
반환 데이터;
},
setData : 함수 (value) {
//`data '의 할당 된 값을 반환합니다
return (data = value);
}
};
}) ();
// 다른 사람들이 여기에 나타납니다
// 모듈을 전역 객체로 바꿉니다
Global.Module = 모듈;
})( 이것 );
// 5.2.1
// 실제 빌드 기능
(기능 (글로벌) {
기능 ctor (foo) {
this.foo = foo;
이것을 반환하십시오;
}
ctor.prototype.getfoo = function () {
이 this.foo;
};
ctor.prototype.setfoo = function (val) {
return (this.foo = val);
};
// 'new'를 사용하여 빌드 함수를 호출하지 않으면 다음을 수행 할 수 있습니다.
var ctor = function (foo) {
새로운 CTOR (FOO)를 반환합니다.
};
// 빌드 함수를 글로벌 객체로 바꿉니다
global.ctor = ctor;
})( 이것 );
6. 이름 지정
A. 당신은 휴먼 컴파일러/압축기가 아니므로 하나로 변환하십시오.
다음 코드는 매우 나쁜 이름의 예입니다.
코드 사본은 다음과 같습니다.
// 6.A.1.1
// 나쁜 이름 지정 예제 코드
함수 Q (s) {
return document.queryselectorall (s);
}
var i, a = [], els = q ( "#foo");
for (i = 0; i <els.length; i ++) {a.push (els [i]);}
당신이 그러한 코드를 작성했다는 것은 의심의 여지가 없습니다. 오늘부터 다시 나타나지 않기를 바랍니다.
다음은 동일한 논리가 있지만 더 강력하고 적절한 이름 지정 (및 읽을 수있는 구조)을 가진 코드는 다음과 같습니다.
코드 사본은 다음과 같습니다.
// 6.A.2.1
// 명명 된 예제 코드를 개선했습니다
함수 쿼리 (선택기) {
return document.queryselectorall (선택기);
}
var idx = 0,
요소 = [],
matches = query ( "#foo"),
길이 = 일치. 길이;
for (; idx <length; idx ++) {
elements.push (일치 [idx]);
}
몇 가지 추가 명명 팁 :
코드 사본은 다음과 같습니다.
// 6.A.3.1
// 이름은 문자열입니다
`개 '는 끈입니다
// 6.A.3.2
// 이름 배열
`[ 'dogs']``개는`개 문자열이 포함 된 배열입니다
// 6.A.3.3
// 이름 함수, 객체, 인스턴스 등
camlcase; 기능 및 var 선언
// 6.A.3.4
// 빌더, 프로토 타입 등 이름을 지정합니다.
파스칼 케이스; 빌드 기능
// 6.A.3.5
// 정규 표현식 이름을 지정합니다
rdesc = //;
// 6.A.3.6
// Google Closure Library 스타일 가이드에서
functionNamesLikethis;
variablenameslikethis;
ConstructorNameslikethis;
enumnameslikethis;
MethodNamesLikethis;
Symbolic_Constants_like_this;
B. 이것에 직면하십시오
잘 알려진 전화 및 적용을 사용하는 것 외에도 .Bind (this) 또는 기능적으로 동등한 것이 항상 선호됩니다. 더 나은 옵션이 없을 때 별칭을 사용하여 후속 통화에 대한 경계 기능 선언을 만듭니다.
코드 사본은 다음과 같습니다.
// 6.B.1
기능 장치 (Opts) {
this.value = null;
// 새 비동기 스트림을 만들면 지속적으로 호출됩니다.
stream.read (opts.path, function (data) {
// 스트림을 사용하여 최신 데이터 값을 반환하고 인스턴스의 값을 업데이트합니다.
this.value = data;
} .bind (this));
// 이벤트 트리거의 빈도를 제어합니다
setInterval (function () {
// 제어 된 이벤트를 게시합니다
this.emit ( "이벤트");
} .bind (this), opts.freq || 100);
}
// 우리가 이벤트 미터를 물려 받았다고 가정합니다.)
실행할 수없는 경우 .Bind와 동등한 것은 대부분의 최신 JavaScript 라이브러리에서 사용할 수 있습니다.
코드 사본은 다음과 같습니다.
// 6.B.2
// 예 : lodash/밑줄, _.bind ()
기능 장치 (Opts) {
this.value = null;
stream.read (opts.path, _.bind (function (data) {
this.value = data;
}, 이것) );
setInterval (_. bind (function () {
this.emit ( "이벤트");
}, this), opts.freq || 100);
}
// 예 : jQuery.proxy
기능 장치 (Opts) {
this.value = null;
stream.read (opts.path, jquery.proxy (함수 (데이터) {
this.value = data;
}, 이것) );
setInterval (jQuery.proxy (function () {
this.emit ( "이벤트");
}, this), opts.freq || 100);
}
// 예 : dojo.hitch
기능 장치 (Opts) {
this.value = null;
stream.read (opts.path, dojo.hitch (this, function (data) {
this.value = data;
});
setInterval (dojo.hitch (this, function () {
this.emit ( "이벤트");
}), opts.freq || 100);
}
자체를 식별자로서 이에 대한 별칭을 만들기위한 후보자를 제공하십시오. 이것은 버그가있을 가능성이 높으며 가능한 한 많이 피해야합니다.
코드 사본은 다음과 같습니다.
// 6.B.3
기능 장치 (Opts) {
var self = 이것;
this.value = null;
stream.read (opts.path, function (data) {
self.value = 데이터;
});
setInterval (function () {
self.emit ( "이벤트");
}, opts.freq || 100);
}
C. thisarg를 사용하십시오
ES 5.1의 여러 프로토 타입 방법에 특별한이 ARG 태그가 내장되어 있으며 가능한 한 많이 사용합니다.
코드 사본은 다음과 같습니다.
// 6.C.1
var obj;
obj = {f : "foo", b : "bar", q : "qux"};
object.keys (obj) .foreach (함수 (키) {
// | this | 이제`obj`입니다
Console.log (이 [키]);
}, obj); // <- 마지막 매개 변수는`thisarg '입니다
// 인쇄 ...
// "foo"
// "술집"
// "qux"
이 ARG는 Array.Prototype.every, array.prototype.foreach, array.prototype.some, array.prototype.map 및 array.prototype.filter에서 사용할 수 있습니다.
7. 기타
이 부분이 설명 할 아이디어와 아이디어는 독단적이지 않습니다. 대신, 일반적인 JavaScript 프로그래밍 작업을 완료하기위한 더 나은 솔루션을 제공하기 위해 기존 관행에 대해 궁금한 점이 더 좋습니다.
A. 스위치 사용을 피하십시오. 현대의 방법 추적은 스위치 표현식으로 블랙리스트 기능을합니다.
Firefox와 Chrome은 모두 스위치 진술을 크게 개선 한 것으로 보입니다. http://jsperf.com/switch-vs-object-literal-vs-module
개선은 여기에서 볼 수 있다는 점에 주목할 가치가 있습니다 : https://github.com/rwldrn/idiomatic.js/issues/13
코드 사본은 다음과 같습니다.
// 7.A.1.1
// switch 문의 예
스위치 (foo) {
사례 "알파":
알파 ();
부서지다;
사례 "베타":
베타();
부서지다;
기본:
// 기본 분기
부서지다;
}
// 7.A.1.2
// 조합과 재사용을 지원할 수있는 메소드는 객체를 사용하여 "케이스"를 저장하는 것입니다.
// 함수를 사용하여 대표단을 수행합니다.
VAR 사례, 대표단;
// 리턴 값은 설명 전용입니다
케이스 = {
알파 : function () {
// 성명
// 리턴 값
반환 [ "알파", arguments.length];
},
베타 : function () {
// 성명
// 리턴 값
반환 [ "베타", arguments.length];
},
_default : function () {
// 성명
// 리턴 값
반환 [ "기본값", arguments.length];
}
};
delegator = function () {
var args, 키, 대표;
//`argument '를 배열로 변환합니다
args = [] .slice.call (인수);
//`argument '에서 마지막 값을 추출합니다
key = args.shift ();
// 기본 브랜치를 호출합니다
Delegate = cases._default;
// 객체에서 메소드를 위임합니다
if (cases.hasownproperty (key)) {
Delegate = cases [key];
}
// arg의 범위는 특정 값으로 설정할 수 있습니다.
//이 경우 | null | 괜찮습니다
return delegate.apply (null, args);
};
// 7.A.1.3
// 7.A.1.2에서 API를 사용합니다.
대표단 ( "알파", 1, 2, 3, 4, 5);
// [ "알파", 5]
// 물론 'case'키의 값은 모든 값으로 쉽게 변경할 수 있습니다.
VAR CASEKEY, DonduserInput;
// 어떤 형태의 입력이 있습니까?
someuserinput = 9;
if (someuserinput> 10) {
CaseKey = "알파";
} 또 다른 {
CaseKey = "베타";
}
// 또는...
Casekey = someuserInput> 10? "알파": "베타";
// 그 다음에...
대표단 (Casekey, donduserinput);
// [ "베타", 1]
// 물론, 이것은 할 수 있습니다 ...
Delegator ();
// [ "기본값", 0]
B. 성능 차이없이 코드의 가독성을 향상시키기 위해 미리 반환 값
코드 사본은 다음과 같습니다.
// 7.B.1.1
// 좋지 않음 :
함수 returnlate (foo) {
var ret;
if (foo) {
ret = "foo";
} 또 다른 {
ret = "quux";
}
반품 반환;
}
// 좋은:
함수 returnearly (foo) {
if (foo) {
"foo"를 반환합니다.
}
"Quux"를 반환합니다.
}
8. 기본 및 호스트 객체 (참고 : 항상 호스트 객체를 번역해서는 안된다고 생각 했으므로 일반적인 글쓰기 방법에 따라 번역 할 것입니다).
가장 기본적인 원칙은 다음과 같습니다.
어리석은 일을하지 마십시오. 일이 항상 좋아질 것입니다.
이 개념을 강화하려면이 데모를보십시오.
Andrew DuPont의 "모든 것이 허용 : 기본 확장"(JSConf2011, 오리건 주 포틀랜드)
http://blip.tv/jsconf/jsconf2011 Andrew-dupont-everythe-Sperment-extending-built-ins-ins-5211542
9. 의견
한 줄의 주석은 코드 위에 첫 번째 선택으로 배치됩니다.
여러 줄은 괜찮습니다
줄 끝의 의견을 피해야합니다!
JSDOC 방법도 좋지만 시간이 더 걸립니다.
10. 하나의 언어 만 사용하십시오
프로그램 관리자 (또는 팀)가 프로그램을 사용한다고 규정하는 언어에 관계없이 프로그램은 동일한 언어로만 작성해야합니다.
충수
먼저 쉼표
이 문서를 기본 스타일 가이드로 사용하는 모든 프로젝트는 저자가 명시 적으로 지정하거나 요구하지 않는 한 사전 코드 코드 형식을 허용하지 않습니다.