최신 JavaScript 개발 프로그래밍 스타일 Idiomatic.js 가이드 중국어 버전_javascript 기술

WBOY
풀어 주다: 2016-05-16 16:46:34
원래의
1437명이 탐색했습니다.

프로젝트에 선택하는 스타일은 최고 수준이어야 합니다. 이를 프로젝트에 설명으로 배치하고 코드 스타일 일관성, 가독성 및 유지 관리 가능성을 보장하기 위해 이 문서에 연결하세요.

1. 공백

1. 공백과 탭을 혼합하지 마세요.
2. 프로젝트를 시작하고 코드를 작성하기 전에 소프트 들여쓰기(공백) 또는 Tab(들여쓰기 방법)을 선택하여 가장 높은 지침으로 사용하세요.
a) 가독성을 위해 저는 항상 편집기에서 2글자 들여쓰기를 디자인하는 것을 권장합니다. 이는 탭 하나 대신 공백 두 개 또는 공백 두 개에 해당합니다.
3. 편집자가 지원하는 경우 항상 "숨겨진 문자 표시" 설정을 켜주세요. 이점은 다음과 같습니다.
a) 일관성 유지
b) 줄 끝의 공백을 제거합니다.
c) 빈 줄의 공백을 제거합니다
d). >

2. 문법을 아름답게

괄호, 중괄호, 줄 바꿈


코드 복사 코드는 다음과 같습니다.
// if/else/for/while/try에는 일반적으로 괄호, 중괄호 및 여러 줄이 있습니다.
// 가독성에 도움이 됩니다
// 2.A.1.1

// 크래핑된 구문의 예

if(조건) doSomething();

(조건) 반복하는 동안 ;

for(var i=0;i // 2.A.1.1

// 가독성 향상을 위해 공백 사용

if ( 조건 ) {

// 명령문
}

while ( 조건 ) {

// 명령문
}

for ( var i = 0; i // 명령문
}
// 더 나은 접근 방식:

var i,

길이 = 100;

for ( i = 0; i // 명령문
}
// 아니면...

var i = 0,

길이 = 100;

for ( ; i // 명령문
}
var prop;

for ( prop in object ) {

// 명령문
}

if ( true ) {

// 명령문
} else {
// 명령문
}

B. 할당, 선언, 함수(명명된 함수, 함수 표현식 , 생성자 함수)

코드 복사 코드는 다음과 같습니다.
// 2.B. 1.1
// 변수
var foo = "bar",
num = 1,
undef;
//리터럴 식별자:

var 배열 = [],
객체 = {};

// 2.B.1.2

// 범위(함수) 내에서 `var` 하나만 사용하면 가독성이 향상됩니다.
// 선언 목록을 체계적으로 정리합니다(키 입력도 절약됩니다)

// 나쁨

var foo = "";
var bar = "";
var qux;

// OK

var foo = "",
bar = "",
quux;

// 또는..

var // 이 변수에 대한 설명
foo = "",
bar = "",
quux;

// 2.B.1.3

// `var` 문은 항상 해당 범위(함수)의 최상위에 있어야 합니다.
// ECMAScript 6의 상수와도 작동합니다

//나쁨

function foo() {

// 변수 앞에 문장이 있습니다

var bar = "",

qux;
}

// OK

function foo() {
var bar = "",
qux;

// 모든 문은 변수 뒤에 있습니다.

}
// 2.B.2.1
// 명명된 함수 선언
function foo( arg1, argN ) {

}

// 사용법

foo( arg1, argN );

// 2.B.2.2

// 명명된 함수 선언
function square( number) {
return number * number;
}

//

사각형( 10 ) 사용 방법

// 매우 부자연스러운 연속 전달 스타일

function square( number, callback) {
callback( number * number );
}

square( 10, function( square ) {

// 콜백 콘텐츠
});

// 2.B.2.3

// 함수 표현식
var square = function( number) {
// 가치 있고 관련 있는 콘텐츠 반환
return number * number
} ;

// 식별자가 있는 함수 식

// 이 기본 형식에는 자신을 호출할 수 있는 추가 기능이 있습니다.
// 스택에 식별자가 있습니다.
var Factorial = function Factorial ( number ) {
if ( 숫자 < 2 ) {
return 1;
}

숫자 반환 * 계승( 숫자-1 );

};

// 2.B.2.4

// 생성자 선언
function FooBar( options) {

this.options = 옵션;

}

// 사용법

var fooBar = new FooBar({ a: "alpha" });

fooBar.options;

// { a: "alpha" }

C. 예외 사항, 세부 사항


코드 복사 코드는 다음과 같습니다.

// 2.C.1.1
// 콜백이 있는 함수
foo(function() {
// 참고: 첫 번째 함수 호출에는 괄호와 `function`이 있습니다. 공백 없음
});

// 이 함수는 공백 없이 `배열`을 매개변수로 허용합니다.
foo([ "alpha", "beta" ]);

// 2.C.1.2
// 이 함수는 공백 없이 `object`를 매개변수로 허용합니다.
foo({
a: "alpha",
b: "beta"
});

// 이 함수는 공백 없이 `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) {
// 명령문
} else {
// 명령문
}


인용문

작은따옴표를 선택하든 큰따옴표를 선택하든 상관없이 JavaScript 구문 분석에는 차이가 없습니다. 반드시 지켜야 할 것은 일관성입니다. 동일한 프로젝트에 두 가지 유형의 인용문을 혼합하지 말고 하나를 선택하고 일관성을 유지하십시오.

F. 줄 끝 및 빈 줄

공백을 두면 구분이 무너지고 변경 내용을 읽을 수 없게 됩니다. 줄 끝과 빈 줄의 공백을 자동으로 제거하려면 사전 커밋 후크를 포함하는 것이 좋습니다.

3. 유형 감지(jQuery 핵심 스타일 지침에서)

A. 직접형(실제형, 실제형)

문자열:

코드 복사 코드는 다음과 같습니다.

변수 유형 == = "string "

번호:
코드 복사 코드는 다음과 같습니다.

변수 유형 = == "숫자"

부울:
코드 복사 코드는 다음과 같습니다. :

변수 유형 === "부울"

객체:
코드 복사 코드는 다음과 같습니다.

typeof 변수 === "object"

배열:
코드 복사 코드는 다음과 같습니다:

Array.isArray( arrayLikeObject )
(가능한 경우)

노드:
코드 복사 코드는 다음과 같습니다.

elem.nodeType === 1

null :
코드 복사 코드는 다음과 같습니다.

변수 === null

null 또는 정의되지 않음:
코드 복사 코드는 다음과 같습니다.

변수 = = null

정의되지 않음:

전역 변수:

코드 복사 코드는 다음과 같습니다.

변수 유형 = == " 정의되지 않음"

지역변수:
코드 복사 코드는 다음과 같습니다.

변수 === 정의되지 않음

속성:
코드 복사 코드는 다음과 같습니다.

object.prop === 정의되지 않음
object.hasOwnProperty( prop )
"prop" in object

B. 변환 유형(강제 유형, 강제 유형)

이것의 의미를 생각해 보세요...

제공된 HTML:

코드 복사 코드는 다음과 같습니다.

// 3.B.1.1

// `foo`에는 `0` 값이 할당되었으며 유형은 `number`입니다.
var foo = 0;

// foo 유형;
// "숫자"
...

// 후속 코드에서는 `foo`를 업데이트하여 입력 요소에서 얻은 새 값을 제공해야 합니다.

foo = document.getElementById("foo-input").value;

// 이제 `typeof foo`를 테스트하면 결과는 `string`이 됩니다.
// 이는 `foo`를 감지하는 if 문이 다음과 유사한 논리를 가지고 있음을 의미합니다.

if ( foo === 1 ) {

importantTask();

}

// `importantTask()`는 `foo`의 값이 "1"인 경우에도 실행되지 않습니다.

// 3.B.1.2

// / - 단항 연산자를 교묘하게 사용하여 유형을 캐스팅하여 문제를 해결할 수 있습니다.

foo = document.getElementById("foo-input").value;
// ^ 단항 연산자는 오른쪽의 피연산자를 `숫자`로 변환합니다

// foo 유형;
// "숫자"

if ( foo === 1 ) {

importantTask();

}

// `importantTask()`가 호출됩니다


캐스트에 대한 몇 가지 예는 다음과 같습니다.
코드 복사 코드는 다음과 같습니다.

// 3.B.2.1

var 숫자 = 1,
문자열 = "1",
bool = false;

숫자;
// 1

숫자 "";
// "1"

문자열;
// "1"

문자열;
// 1

문자열 ;
// 1

문자열;
// 2

부울;
//거짓

부울;
// 0

bool "";
// "false"
// 3.B.2.2

var 숫자 = 1,
문자열 = "1",
bool = true;

문자열 === 숫자;
// false

문자열 === 숫자 "";
// 참

문자열 === 숫자;
// 참

bool === 숫자;
// false

bool === 숫자;
// true

bool === 문자열;
// false

bool === !!string;
// true
// 3.B.2.3

var 배열 = [ "a", "b", "c" ];

!!~array.indexOf("a");
// true

!!~array.indexOf("b");
// true

!!~array.indexOf("c");
// true

!!~array.indexOf("d");
// false

// 위의 내용이 "불필요하게 영리하다"는 점은 주목할 가치가 있습니다.
// 반환된 값을 비교하려면 명확한 솔루션을 사용하세요. ​​​​
// indexOf와 같은:

if ( array.indexOf( "a" ) >= 0 ) {
// ...
}
// 3.B.2.3

변수 번호 = 2.5;

parseInt( num, 10 );

// 다음과 같습니다...

~~개;

숫자 >> 0;

숫자 >>> 0;

//결과는 항상 2입니다

// 음수 값은 다르게 취급된다는 점을 항상 명심하세요...

var neg = -2.5;

parseInt( 부정, 10 );

// 다음과 같습니다...

~~부정;

부정 >>0;

// 결과는 항상 -2입니다
// 하지만...

부정 >>>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, 정의되지 않음, NaN과 일치합니다
// 부울 유형이 _반드시_ false여야 하는 경우 다음과 같이 사용하세요. if ( foo === false ) ...

// 4.1.7

// 참조를 계산하려는 경우 null이거나 정의되지 않을 수 있지만 false는 "" 또는 0이 아닙니다.
// 다음을 사용하는 대신:
if ( foo === null || foo === 정의되지 않음 ) ...

// ...다음과 같이 == 유형 캐스팅의 이점을 누려보세요.

if ( foo == null ) ...

// ==를 사용하면 `null`은 `null` 및 `undefine`과 일치하게 됩니다

// `false`, "" 또는 0은 일치하지 않습니다
null == undefine

항상 가장 좋고 가장 정확한 값을 판단하십시오. 위의 내용은 교리가 아닌 지침입니다.


코드 복사 코드는 다음과 같습니다.
// 4.2.1
/ / 타입 변환 및 비교 연산 지침
// `===` 먼저, `==` 두 번째(느슨하게 형식화된 비교가 필요한 경우 제외)

// `===`은 유형 변환을 수행하지 않습니다. 이는 다음을 의미합니다.

"1" === 1;

// 거짓

// `==`는 유형을 변환합니다. 이는 다음을 의미합니다.

"1" == 1;

// 참

// 4.2.2

// 부울, 참 및 거짓

// 부울:

참, 거짓

// 참:

"foo", 1

// 의사:

"", 0, null, 정의되지 않음, NaN, void 0

5. 실용적인 스타일

코드 복사 코드는 다음과 같습니다.
// 5.1.1
// 실용적인 모듈
(함수( 전역 ) {

var Module = (함수() {

var 데이터 = "비밀";

return {

// 부울 값입니다.
bool: true,
bool: true,
// 문자열
문자열: "a string",
/ / 배열
배열: [ 1, 2, 3, 4 ],
// 객체
객체: {
lang: "en-Us"
},
getData : function() {
                                                                                   > }
};
})();

// 여기에 다른 사람들도 나타날 것입니다

// 모듈을 전역 객체로 변환
global.Module = Module;

})( 이 );

// 5.2.1

// 실용적인 구성 기능

(함수( 전역 ) {

함수 Ctor( foo ) {


this.foo = foo;

이것을 돌려주세요;

}

Ctor.prototype.getFoo = function() {

return this.foo;

};


Ctor.prototype.setFoo = function( val ) {

return ( this.foo = val );

};

// `new`를 사용하여 생성자를 호출하는 대신 다음을 수행할 수 있습니다.

var ctor = function( foo ) {

return new 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
의심할 바 없이 그러한 코드를 작성하셨을 것입니다. 오늘부터 다시는 나타나지 않기를 바랍니다.

다음은 동일한 논리에 대한 코드이지만 더 강력하고 적절한 이름 지정(및 읽기 쉬운 구조)을 사용합니다.

코드 복사 코드는 다음과 같습니다.

// 6.A.2.1
// 네이밍 예시 코드 개선

함수 쿼리( selector ) {
return document.querySelectorAll( selector );
}

var idx = 0,
elements = [],
match = query("#foo"),
length = match.length;

for ( ; idx < length; idx ) {
elements.push( match[ idx ] );
}


몇 가지 추가 명명 팁:
코드 복사 코드는 다음과 같습니다.

// 6.A.3.1
// Named string

`dog`은 문자열입니다

// 6.A.3.2
// 명명된 배열

`['dogs']`는 `dog 문자열을 포함하는 배열

입니다.

// 6.A.3.3
// 이름이 지정된 함수, 개체, 인스턴스 등

camlCase; 함수 및 var 선언

// 6.A.3.4
// 명명된 빌더, 프로토타입 등

PascalCase 생성자 함수

// 6.A.3.5
// 명명된 정규 표현식

rDesc = //;

// 6.A.3.6
// Google Closure 라이브러리 스타일 가이드에서

functionNamesLikeThis;
variableNamesLikeThis;
ConstructorNamesLikeThis;
EnumNamesLikeThis;
methodNamesLikeThis;
SYMBOLIC_CONSTANTS_LIKE_THIS;


B.

잘 알려진 호출 및 적용 외에도 항상 .bind( this ) 또는 이와 동등한 기능을 선호하세요. 더 나은 대안이 없는 경우에만 별칭을 사용하여 후속 호출에 대한 BoundFunction 선언을 만듭니다.


코드 복사 코드는 다음과 같습니다.
// 6.B.1
기능 장치(선택) {

this.value = null;

// 지속적으로 호출될 새로운 비동기 스트림을 생성합니다.

stream.read( opts.path, function( data ) {

// 스트림을 사용하여 최신 데이터 값을 반환하고 인스턴스 값을 업데이트합니다.

this.value = data;

}.bind(this) );

// 이벤트 트리거 빈도 제어

setInterval(function() {

// 제어된 이벤트 발생

this.emit("event");

}.bind(this), opts.freq || 100 );

}

// 이벤트 이미터(EventEmitter)를 상속받았다고 가정합니다. ;)

이 방법이 작동하지 않으면 대부분의 최신 JavaScript 라이브러리에서 .bind와 동일한 기능을 사용할 수 있습니다.


코드 복사 코드는 다음과 같습니다.
// 6.B.2

// 예: lodash/underscore, _.bind()

function Device( opts ) {

this.value = null;

stream.read( opts.path, _.bind(function( data ) {

this.value = 데이터;

}, 이) );

setInterval(_.bind(function() {

this.emit("이벤트");

}, 이), opts.freq || 100 );

}

// 예: jQuery.proxy

function Device( opts ) {

this.value = null;

stream.read( opts.path, jQuery.proxy(function( data ) {

this.value = 데이터;

}, 이) );

setInterval( jQuery.proxy(function() {

this.emit("이벤트");

}, 이), opts.freq || 100 );

}

// 예: dojo.hitch

function Device( opts ) {

this.value = null;

stream.read( opts.path, dojo.hitch( this, function( data ) {

this.value = 데이터;

}) );

setInterval( dojo.hitch( this, function() {

this.emit("이벤트");

}), opts.freq || 100 );

}


self를 식별자로 사용하여 별칭을 생성할 후보를 제공하세요. 이는 버그가 많으므로 가능하면 피해야 합니다.

코드 복사 코드는 다음과 같습니다.

// 6.B.3

기능 장치( opts ) {
var self = this;

this.value = null;

stream.read( opts.path, function( data ) {

self.value = 데이터;

});

setInterval(함수() {

self.emit("이벤트");

}, opts.freq || 100 );
}

C. 이 Arg를 사용하세요

ES 5.1의 여러 프로토타입 메소드에는 특수 thisArg 태그가 내장되어 있으므로 이를 최대한 사용하세요.

코드 복사 코드는 다음과 같습니다.

// 6.C.1

var obj;

obj = { f: "foo", b: "bar", q: "qux" };

Object.keys( obj ).forEach(function( 키 ) {

// |이것은 이제 `obj`입니다

console.log( this[ 키 ] );

}, obj ); // <-- 마지막 매개변수는 `thisArg`입니다.

//인쇄해 보세요...

// "foo"
// "bar"
// "qux"


thisArg는 Array.prototype.every, Array.prototype.forEach, Array에 있습니다. 프로토타입 .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문 예시

switch( foo ) {
case "alpha":
alpha();
break;
case "beta":
beta();
break;
default:
//기본 브랜치
break;
}

// 7.A.1.2
// 구성 및 재사용을 지원하는 한 가지 방법은 객체를 사용하여 "케이스"를 저장하는 것입니다.
// 함수를 사용하여 위임:

var 케이스, 위임자;

// 반환 값은 설명용입니다.
cases = {
alpha: function() {
// 명령문
// 반환 값
return [ "Alpha", 인수 .length ];
},
beta: function() {
// 명령문
// 반환 값
return [ "Beta",args.length ];
} ,
_default: function() {
// 명령문
// 반환 값
return [ "Default",args.length ];
}
};

delegator = function() {
var args, key, Delegate;

// `argument`를 배열로 변환
args = [].slice.call( 인수 );

// `인수`에서 첫 번째 값 추출
key = args.shift();

// 기본 브랜치 호출
대리자 = 케이스._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, someUserInput;

// 일종의 입력일 가능성이 있나요?
someUserInput = 9;

if ( someUserInput > 10 ) {
caseKey = "alpha";
} else {
caseKey = "beta";
}

// 아니면...

caseKey = someUserInput > 10 ? "alpha" : "beta";

// 그럼...

위임자( caseKey, someUserInput );
// [ "베타", 1 ]

// 물론 이렇게 해도 됩니다...

delegator();
// [ "기본값", 0 ]

B. 값을 일찍 반환하면 성능 차이가 크지 않고 코드의 가독성이 향상됩니다

코드 복사 코드는 다음과 같습니다. 다음 :

// 7.B.1.1
// 나쁨:
function returnLate( foo ) {
var ret;

if ( foo ) {
ret = "foo";
} else {
ret = "quux";
}
return ret;
}

// 알겠습니다:

함수 returnEarly( foo ) {

if ( foo ) {
return "foo";
}
return "quux";
}

8. 네이티브 및 호스트 개체(참고: 사실 호스트 개체는 번역하면 안 된다고 늘 느껴왔기 때문에 일반 책에 적힌 대로 번역하겠습니다)

가장 기본적인 원칙은 다음과 같습니다.

쓸데없는 짓은 하지 마세요. 상황이 좋아질 거예요.

이 아이디어를 강화하려면 다음 데모를 시청하세요.

Andrew Dupont의 "모든 것이 허용됩니다: 기본 확장"(JSConf2011, 오레곤주 포틀랜드)

http://blip.tv/jsconf/jsconf2011-andrew-dupont-everything-is-permitted-extending-built-ins-5211542

9. 참고사항

코드 위에 한 줄 주석을 선호합니다
여러 줄도 가능합니다
줄 끝 주석은 피해야 합니다!
JSDoc 방식도 좋지만 시간이 더 걸립니다

10. 한 가지 언어를 사용하세요

프로그램은 프로그램 관리자(또는 팀)가 지정한 언어에 관계없이 동일한 언어로만 작성되어야 합니다.

부록

쉼표 먼저

이 문서를 기본 스타일 가이드로 사용하는 모든 프로젝트는 작성자가 명시적으로 지정하거나 요청하지 않는 한 앞에 쉼표가 있는 코드 형식을 허용하지 않습니다.

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿