prerequisites.html 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. <!DOCTYPE html><html lang="ko"><head>
  2. <meta charset="utf-8">
  3. <title>먼저 알아야 할 것들</title>
  4. <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
  5. <meta name="twitter:card" content="summary_large_image">
  6. <meta name="twitter:site" content="@threejs">
  7. <meta name="twitter:title" content="Three.js – 먼저 알아야 할 것들">
  8. <meta property="og:image" content="https://threejs.org/files/share.png">
  9. <link rel="shortcut icon" href="../../files/favicon_white.ico" media="(prefers-color-scheme: dark)">
  10. <link rel="shortcut icon" href="../../files/favicon.ico" media="(prefers-color-scheme: light)">
  11. <link rel="stylesheet" href="../resources/lesson.css">
  12. <link rel="stylesheet" href="../resources/lang.css">
  13. <!-- Import maps polyfill -->
  14. <!-- Remove this when import maps will be widely supported -->
  15. <script async src="https://unpkg.com/[email protected]/dist/es-module-shims.js"></script>
  16. <script type="importmap">
  17. {
  18. "imports": {
  19. "three": "../../build/three.module.js"
  20. }
  21. }
  22. </script>
  23. <link rel="stylesheet" href="/manual/ko/lang.css">
  24. </head>
  25. <body>
  26. <div class="container">
  27. <div class="lesson-title">
  28. <h1>먼저 알아야 할 것들</h1>
  29. </div>
  30. <div class="lesson">
  31. <div class="lesson-main">
  32. <p>이 시리즈는 Three.js에 입문하는 초심자를 위한 튜토리얼입니다. 이 시리즈는
  33. 독자가 최소한 자바스크립트 기본 프로그래밍에 익숙하며, DOM이 무엇인지 설명할
  34. 수 있고, HTML과 자바스크립트로 DOM 요소를 조작할 수 있다는 전제 하에 작성하였습니다.
  35. 또한 <code class="notranslate" translate="no">&lt;script type="module"&gt;</code> 태그로 <a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/import">ES2015 모듈</a>을
  36. 불러올 수 있으며, <a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS/Selectors">CSS 셀렉터가 무엇인지</a>도
  37. 알고, ES5, ES2015, 약간의 ES2016도 알며, 브라우저가 자바스크립트를 이벤트와 콜백으로만
  38. 실행한다는 것도 알고, 클로저가 무엇인지까지 안다고 가정했죠.</p>
  39. <p>이번 글에서는 시리즈를 읽는 데 필요한 이런 기본 전제에 대해 간단히 환기하고
  40. 넘어가겠습니다.</p>
  41. <h2 id="es2015-">ES2015 모듈</h2>
  42. <p>ES2015 모듈은 스크립트 안에서 <code class="notranslate" translate="no">import</code> 키워드나, 인라인 <code class="notranslate" translate="no">&lt;script type="module"&gt;</code>
  43. 태그로 불러올 수 있습니다. 두 가지 예시를 동시에 써보죠.</p>
  44. <pre class="prettyprint showlinemods notranslate lang-html" translate="no">&lt;script type="module"&gt;
  45. import * as THREE from 'three';
  46. ...
  47. &lt;/script&gt;
  48. </pre>
  49. <p>모듈의 경로는 반드시 상대 경로나 절대 경로여야 합니다. <code class="notranslate" translate="no">&lt;img&gt;</code>, <code class="notranslate" translate="no">&lt;a&gt;</code> 태그, CSS 경로와
  50. 달리 여기서 상대 경로란 <code class="notranslate" translate="no">./</code>이나 <code class="notranslate" translate="no">../</code>로 시작하는 경로를 말합니다.</p>
  51. <p>더 자세한 것은 <a href="fundamentals.html">이 글</a>의 마지막 부분을 참고하세요.</p>
  52. <h2 id="-document-queryselector-document-queryselectorall-"><code class="notranslate" translate="no">document.querySelector</code>와 <code class="notranslate" translate="no">document.querySelectorAll</code></h2>
  53. <p>요소를 선택할 때는 <code class="notranslate" translate="no">document.querySelector</code>나 <code class="notranslate" translate="no">document.querySelectorAll</code>을
  54. 사용하면 됩니다. 첫 번째는 CSS 셀렉터와 일치하는 첫 번째 요소를 반환하고, 두 번째는
  55. CSS 셀렉터와 일치하는 모든 요소를 반환하죠.</p>
  56. <h2 id="-onbody-"><code class="notranslate" translate="no">onbody</code>를 쓰지 마세요</h2>
  57. <p>옛날에 개발된 많은 페이지가 body 태그의 onload 속성을 사용합니다.</p>
  58. <pre class="prettyprint showlinemods notranslate notranslate" translate="no">&lt;body onload="somefunction()"&gt;
  59. </pre><p>이런 스타일은 더 이상 권장하지 않습니다. script 태그를 페이지의 끝에 삽입하세요.</p>
  60. <pre class="prettyprint showlinemods notranslate lang-html" translate="no">&lt;html&gt;
  61. &lt;head&gt;
  62. ...
  63. &lt;/head&gt;
  64. &lt;body&gt;
  65. ...
  66. &lt;/body&gt;
  67. &lt;script&gt;
  68. // inline javascript
  69. &lt;/script&gt;
  70. &lt;/html&gt;
  71. </pre>
  72. <p>또는 <a href="https://developer.mozilla.org/ko/docs/Web/HTML/Element/script"><code class="notranslate" translate="no">defer</code> 속성을 사용</a>하는
  73. 것이 좋습니다.</p>
  74. <h2 id="-closure-">클로저(closure)란?</h2>
  75. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">function a(v) {
  76. const foo = v;
  77. return function() {
  78. return foo;
  79. };
  80. }
  81. const f = a(123);
  82. const g = a(456);
  83. console.log(f()); // 123 출력
  84. console.log(g()); // 456 출력
  85. </pre>
  86. <p>위 예제에서 함수 <code class="notranslate" translate="no">a</code>는 매번 호출할 때마다 새로운 함수를 반환합니다. 이는 상수 <code class="notranslate" translate="no">foo</code>에
  87. 대한 <em>클로저</em>이죠. 자세한 건 <a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Closures">여기</a>를
  88. 참고하기 바랍니다.</p>
  89. <h2 id="-this-"><code class="notranslate" translate="no">this</code> 이해하기</h2>
  90. <p><code class="notranslate" translate="no">this</code>는 마법이 아닙니다. <code class="notranslate" translate="no">this</code>는 다른 인자들처럼 자동으로 함수에 넘겨지는 일종의 변수이죠.
  91. 간단히 함수를 직접 호출하는 경우를 예로 들어보겠습니다.</p>
  92. <pre class="prettyprint showlinemods notranslate notranslate" translate="no">somefunction(a, b, c);
  93. </pre><p>여기서 <code class="notranslate" translate="no">this</code>는 <code class="notranslate" translate="no">null</code>입니다(엄격(strict) 모드나 모듈 안에서). 반면 <code class="notranslate" translate="no">.</code> 연산자를 붙여 메서드로
  94. 호출하는 경우,</p>
  95. <pre class="prettyprint showlinemods notranslate notranslate" translate="no">someobject.somefunction(a, b, c);
  96. </pre><p><code class="notranslate" translate="no">this</code>는 <code class="notranslate" translate="no">someobject</code>로 지정될 겁니다.</p>
  97. <p>많은 사람들이 헷갈리는 부분은 메서드를 콜백 처리할 때이죠.</p>
  98. <pre class="prettyprint showlinemods notranslate notranslate" translate="no"> const callback = someobject.somefunction;
  99. loader.load(callback);
  100. </pre><p>자바스크립트에 능숙하지 않은 사람이 보기에는 문제가 없을지 모르나, <code class="notranslate" translate="no">loader.load</code>는 콜백 함수를
  101. <code class="notranslate" translate="no">.</code> 연산자를 써서 호출하지 않으므로-loader가 별도로 <code class="notranslate" translate="no">this</code>를 지정하지 않는 한-<code class="notranslate" translate="no">this</code>는 null이
  102. 됩니다. 콜백 함수를 호출할 때 <code class="notranslate" translate="no">this</code>를 <code class="notranslate" translate="no">someobject</code>로 지정하려면 명시적으로 <code class="notranslate" translate="no">this</code>를 종속시켜야(binding)
  103. 합니다.</p>
  104. <pre class="prettyprint showlinemods notranslate notranslate" translate="no"> const callback = someobject.somefunction.bind(someobject);
  105. loader.load(callback);
  106. </pre><p><code class="notranslate" translate="no">this</code>를 이해하기 어렵다면, <a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this"><em>this</em>에 관한 문서</a>를
  107. 한 번 읽어보길 권합니다.</p>
  108. <h2 id="es5-es2015-es2016">ES5/ES2015/ES2016</h2>
  109. <h3 id="-var-const-let-"><code class="notranslate" translate="no">var</code> 대신 <code class="notranslate" translate="no">const</code>와 <code class="notranslate" translate="no">let</code> 사용하기</h3>
  110. <p><code class="notranslate" translate="no">const</code>와 <code class="notranslate" translate="no">let</code>을 쓸 수 있는 환경에서 <code class="notranslate" translate="no">var</code>를 써야할 이유는 <em>전혀</em> 없고, 지금 <code class="notranslate" translate="no">var</code>를 사용하는
  111. 것은 실력 향상에 전혀 도움이 되지 않습니다. 변수를 재할당할 일이 없을 경우 <code class="notranslate" translate="no">const</code>를 사용하세요.
  112. 변수를 재할당하는 것은 흔치 않은 일이니, 주로 <code class="notranslate" translate="no">const</code>를 더 많이 쓰게 될 겁니다. 변수의 값을 바꿔야
  113. 한다면 <code class="notranslate" translate="no">let</code>을 사용하세요. 이런 습관을 들이면 버그를 훨씬 더 많이 줄일 수 있습니다.</p>
  114. <h3 id="-for-elem-in-collection-for-elem-of-collection-"><code class="notranslate" translate="no">for(elem in collection)</code> 대신 <code class="notranslate" translate="no">for(elem of collection)</code> 사용하기</h3>
  115. <p><code class="notranslate" translate="no">for of</code>는 <code class="notranslate" translate="no">for in</code>의 문제를 해결하기 위해 새로 추가된 문법입니다.</p>
  116. <p>예를 들어 객체의 키/값 쌍을 반복문으로 돌릴 경우 다음과 같이 쓸 수 있죠.</p>
  117. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">for (const [key, value] of Object.entries(someObject)) {
  118. console.log(key, value);
  119. }
  120. </pre>
  121. <h3 id="-foreach-map-filter-"><code class="notranslate" translate="no">forEach</code>, <code class="notranslate" translate="no">map</code>, <code class="notranslate" translate="no">filter</code> 등을 적절히 활용하기</h3>
  122. <p>ES5에서 배열에 <a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach"><code class="notranslate" translate="no">forEach</code></a>,
  123. <a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/map"><code class="notranslate" translate="no">map</code></a>
  124. 메서드 등이 추가되었고, ES2015에서는 <a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/filter"><code class="notranslate" translate="no">filter</code></a>
  125. 메서드 등 여러 유용한 메서드가 추가되었습니다.</p>
  126. <h3 id="-destructuring-">구조분해할당(destructuring) 사용하기</h3>
  127. <p><code class="notranslate" translate="no">const dims = { width: 300, height: 150 }</code>. 이런 객체가 있다고 해보죠. 객체의
  128. 각 속성을 별도의 변수에 할당하고자 합니다.</p>
  129. <p>기존 방법</p>
  130. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const width = dims.width;
  131. const height = dims.height;
  132. </pre>
  133. <p>새로운 방법</p>
  134. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const { width, height } = dims;
  135. </pre>
  136. <p>구조분해할당은 배열에도 적용할 수 있습니다. <code class="notranslate" translate="no">const position = [1, 2, 3, 4]</code>.
  137. 이런 배열이 있다고 해보죠.</p>
  138. <p>기존 방법</p>
  139. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const x = position[2];
  140. const y = position[1];
  141. </pre>
  142. <p>새로운 방법</p>
  143. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const [ , y, x ] = position;
  144. </pre>
  145. <p>또한 매개변수에도 구조분해할당을 적용할 수 있습니다.</p>
  146. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const dims = { width: 300, height: 150 };
  147. const position = [1, 2, 3, 4];
  148. function distFromOrig([x, y]) {
  149. return Math.sqrt(x * x + y * y);
  150. }
  151. const dist = distFromOrig(position); // dist = 2.236...
  152. function area({ width, height }) {
  153. return width * height;
  154. }
  155. const a = area(dims); // a = 45000
  156. </pre>
  157. <h3 id="-">객체 선언 시 축약 문법 사용</h3>
  158. <p>기존 방법</p>
  159. <pre class="prettyprint showlinemods notranslate lang-js" translate="no"> const width = 300;
  160. const height = 150;
  161. const obj = {
  162. width: width,
  163. height: height,
  164. area: function() {
  165. return this.width * this.height
  166. },
  167. };
  168. </pre>
  169. <p>새로운 방법</p>
  170. <pre class="prettyprint showlinemods notranslate lang-js" translate="no"> const width = 300;
  171. const height = 150;
  172. const obj = {
  173. width,
  174. height,
  175. area() {
  176. return this.width * this.height;
  177. },
  178. };
  179. </pre>
  180. <h3 id="-">전개 연산자 <code class="notranslate" translate="no">...</code> 사용하기</h3>
  181. <p>전개 연산자는 매우 유용합니다. 예를 들어보죠.</p>
  182. <pre class="prettyprint showlinemods notranslate lang-js" translate="no"> function log(className, ...args) {
  183. const elem = document.createElement('div');
  184. elem.className = className;
  185. elem.textContent = args.join(' ');
  186. document.body.appendChild(elem);
  187. }
  188. </pre>
  189. <p>또 배열을 인자로 넘겨줄 때도 유용합니다.</p>
  190. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const position = [1, 2, 3];
  191. somemesh.position.set(...position);
  192. </pre>
  193. <p>배열을 얕은 복사할 때 사용할 수도 있고</p>
  194. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const copiedPositionArray = [...position];
  195. copiedPositionArray.push(4); // [1,2,3,4]
  196. console.log(position); // [1,2,3] 기존 배열은 영향을 받지 않음
  197. </pre>
  198. <p>객체를 합칠 때도 사용할 수 있죠.</p>
  199. <pre class="prettyprint showlinemods notranslate notranslate" translate="no">const a = { abc: 123 };
  200. const b = { def: 456 };
  201. const c = { ...a, ...b }; // c = { abc: 123, def: 456 }
  202. </pre><h3 id="-class-"><code class="notranslate" translate="no">class</code> 사용하기</h3>
  203. <p>ES5 이하의 문법으로 클래스 스타일의 객체를 만드는 방법은 다른 개발자들에게 낯선 요소
  204. 중 하나였습니다. ES2015부터는 C++/C#/Java 등 다른 객체지향 언어처럼 <a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Classes"><code class="notranslate" translate="no">class</code> 키워드를 사용</a>해
  205. 클래스를 생성할 수 있습니다.</p>
  206. <h3 id="getter-setter">getter와 setter</h3>
  207. <p>모던 프로그래밍 언어에는 대부분
  208. <a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/get">getter</a>와
  209. <a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/set">setter</a>가
  210. 있습니다. ES2015의 <code class="notranslate" translate="no">class</code> 문법을 사용하면 훨씬 쉽게 getter와 setter를 설정할 수 있죠.</p>
  211. <h3 id="-arrow-function-">화살표 함수(arrow function) 활용하기</h3>
  212. <p>화살표 함수는 특히 콜백과 프로미스를 처리할 때 유용합니다.</p>
  213. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">loader.load((texture) =&gt; {
  214. // 불러온 텍스처를 사용
  215. });
  216. </pre>
  217. <p>화살표 함수는 <code class="notranslate" translate="no">this</code> 값을 지정하지 않습니다.</p>
  218. <p>(※ 원문에서는 "Arrow functions bind <code class="notranslate" translate="no">this</code>.(화살표 함수는 <code class="notranslate" translate="no">this</code>를 바인딩한다.)"라고 적었지만,
  219. 표준에 기재된 바 화살표 함수는 익명 함수로 <code class="notranslate" translate="no">this</code>, <code class="notranslate" translate="no">arguments</code>, <code class="notranslate" translate="no">super</code> 또는 <code class="notranslate" translate="no">new.target</code>을 지정하지
  220. 않습니다. 혼돈을 막기 위해 달리 번역하였으니 참고 바랍니다. 역주. 출처: <a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/%EC%95%A0%EB%A1%9C%EC%9A%B0_%ED%8E%91%EC%85%98">MDN</a>)</p>
  221. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const foo = (args) =&gt; {/* code */};
  222. </pre>
  223. <p>위 예제는 다음과 과 같죠.</p>
  224. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const foo = (function(args) {/* code */}).bind(this));
  225. </pre>
  226. <h3 id="-promise-async-await">프로미스(Promise)와 async/await</h3>
  227. <p>프로미스는 비동기 처리를 도와줍니다. async/await는 프로미스를 좀 더 쉽게 쓰도록 도와주죠.</p>
  228. <p>이 둘은 짧게 다루기 어려우므로 다른 글(<a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Using_promises">프로미스</a>,
  229. <a href="https://developer.mozilla.org/ko/docs/Learn/JavaScript/Asynchronous/Async_await">async/await</a>)을
  230. 참고하기 바랍니다.</p>
  231. <h3 id="-template-literals-">템플릿 리터럴(Template Literals)</h3>
  232. <p>템플릿 리터럴은 따옴표 대신 백틱(backticks, 억음 부호)을 사용한 문자열입니다.</p>
  233. <pre class="prettyprint showlinemods notranslate notranslate" translate="no">const foo = `템플릿 리터럴 문자열입니다`;
  234. </pre><p>템플릿 리터럴은 문자열에 2가지 기능을 더한 것인데요. 하나는 여러 줄에 걸쳐 쓸 수
  235. 있는 기능입니다.</p>
  236. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const foo = `템플릿
  237. 리터럴
  238. 문자열입니다`;
  239. const bar = "템플릿\n리터럴\n문자열입니다";
  240. </pre>
  241. <p>예제의 <code class="notranslate" translate="no">foo</code>와 <code class="notranslate" translate="no">bar</code>는 같은 문자열이죠.</p>
  242. <p>다른 하나는 문자열 중간에 자바스크립트 표현식을 끼워넣을 수 있는 기능으로,
  243. <code class="notranslate" translate="no">${ 자바스크립트 표현식 }</code>처럼 사용합니다.</p>
  244. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const r = 192;
  245. const g = 255;
  246. const b = 64;
  247. const rgbCSSColor = `rgb(${r},${g},${b})`;
  248. </pre>
  249. <p>함수를 실행하거나</p>
  250. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const color = [ 192, 255, 64 ];
  251. const rgbCSSColor = `rgb(${ color.join(',') })`;
  252. </pre>
  253. <p>계산식을 넣을 수도 있습니다.</p>
  254. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const aWidth = 10;
  255. const bWidth = 20;
  256. someElement.style.width = `${ aWidth + bWidth }px`;
  257. </pre>
  258. <h1 id="-coding-convection-">자바스크립트 네이밍 컨벤션(coding convection, 코딩 스타일 규약) 지키기</h1>
  259. <p>코드를 작성하는 것은 여러분의 자유지만, 웬만하면 한 가지 규약은 지키는 것이 좋습니다.
  260. 자바스크립트의 변수, 메서드, 함수 이름은 전부 lowerCamelCase이죠. 생성자나, 클래스의
  261. 이름은 UpperCamelCase입니다. 이 규약만 따른다면 자바스크립트의 세계에서 크게 문제될
  262. 것은 없죠. 대부분의 <a href="https://eslint.org">린터(linter)</a>나 린팅 프로그램이 위 네이밍
  263. 컨벤션을 지키지 않는 코드에 대해 에러나 경고를 던집니다.</p>
  264. <p>(※ 문서에 따라 lower camel case는 camelCase, upper camel case는 PascalCase로 부르기도
  265. 합니다. 역주.)</p>
  266. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const v = new vector(); // 모든 클래스가 대문자로 시작할 경우 에러
  267. const v = Vector(); // 모든 함수가 소문자로 시작할 경우 에러
  268. </pre>
  269. <h1 id="visual-studio-code-">Visual Studio Code 사용해보기</h1>
  270. <p>이 세상에는 훌륭한 에디터가 많습니다. 자신이 좋아하는 에디터를 쓰는 것이 가장
  271. 좋죠. 하지만 아직 마음에 드는 자바스크립트 에디터가 없다면 <a href="https://code.visualstudio.com/">Visual Studio Code</a>를
  272. 써보세요! 에디터를 설치하고 <a href="https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint">eslint를 설정</a>
  273. 하면-환경에 따라 시간이 좀 걸릴지 모르나-무수한 자바스크립트 코드의 버그를
  274. 잡는 데 도움이 될 겁니다.</p>
  275. <p>예를 들어 <a href="https://eslint.org/docs/rules/no-undef"><code class="notranslate" translate="no">no-undef</code> 규칙</a>을 활성화하면
  276. VSCode는 ESLint를 통해 변수의 값이 지정되지 않은 경우 경고를 출력할 겁니다.</p>
  277. <div class="threejs_center"><img style="width: 615px;" src="../resources/images/vscode-eslint-not-defined.png"></div>
  278. <p>위 예시에서 작성자는 <code class="notranslate" translate="no">doTheThing</code> 함수를 <code class="notranslate" translate="no">doThing</code>로 잘못 적었습니다. 그러자 <code class="notranslate" translate="no">doThing</code>
  279. 아래에 밑줄이 생겼죠. 그리고 그 위에 커서를 올리면 해당 함수를 선언하지 않았다고
  280. 알려줍니다. 미리 에러를 하나 줄인 셈이죠.</p>
  281. <p><code class="notranslate" translate="no">THREE</code>를 쓸 때도 경고가 나타날 것이므로 코드 상단에 <code class="notranslate" translate="no">/* global THREE */</code>를 선언해
  282. <code class="notranslate" translate="no">THREE</code>가 미리 선언되었음을 알려줄 수 있습니다.</p>
  283. <div class="threejs_center"><img style="width: 615px;" src="../resources/images/vscode-eslint-not-a-constructor.png"></div>
  284. <p>위 이미지에서 ESLint는 <code class="notranslate" translate="no">대문자로 시작하는 이름</code>은 생성자이니 <code class="notranslate" translate="no">new</code> 키워드를 사용하라고
  285. 알려줍니다. <a href="https://eslint.org/docs/rules/new-cap"><code class="notranslate" translate="no">new-cap</code> 규칙</a> 덕에 에러를 하나
  286. 더 줄였네요.</p>
  287. <p>이 외에도 <a href="https://eslint.org/docs/rules/">설정할 수 있는 규칙</a>이 거의 100개 정도 더
  288. 있습니다. 아까 <code class="notranslate" translate="no">var</code> 대신 <code class="notranslate" translate="no">const</code>와 <code class="notranslate" translate="no">let</code>을 쓰라고 했었죠.</p>
  289. <p>아래 이미지에서 작성자는 <code class="notranslate" translate="no">var</code>를 썼는데, <code class="notranslate" translate="no">let</code>이나 <code class="notranslate" translate="no">const</code>를 쓰라는 경고를 받았습니다.</p>
  290. <div class="threejs_center"><img style="width: 615px;" src="../resources/images/vscode-eslint-var.png"></div>
  291. <p>또 <code class="notranslate" translate="no">let</code>을 쓰고 재할당을 하지 않자 <code class="notranslate" translate="no">const</code>를 쓰라고 제안합니다.</p>
  292. <div class="threejs_center"><img style="width: 615px;" src="../resources/images/vscode-eslint-let.png"></div>
  293. <p>물론 <code class="notranslate" translate="no">var</code>가 더 좋다고 생각하면 이 규칙을 꺼버리면 됩니다. 이 규칙을 쓰는 건 제가 성능과
  294. 버그 예방 면에서 <code class="notranslate" translate="no">var</code>보다 <code class="notranslate" translate="no">let</code>과 <code class="notranslate" translate="no">const</code>를 쓰는 걸 더 좋아하기 때문이죠.</p>
  295. <p>일부 파일이나 코드의 일부분에서 규칙을 덮어 씌워야 할 경우, <a href="https://eslint.org/docs/user-guide/configuring#disabling-rules-with-inline-comments">주석을 추가해 규칙을 끌 수
  296. 있습니다</a>.</p>
  297. <h1 id="-">구형 브라우저를 지원해야 한다면 트랜스파일러를 쓰세요</h1>
  298. <p>대부분의 모던 브라우저가 자동 업데이트 기능을 사용하기에 최신 문법을 사용해 생산성과
  299. 버그 예방 두 마리의 토끼를 동시에 잡을 수 있습니다. 만약 꼭 구형 브라우저를 지원해야
  300. 한다면 <a href="https://babeljs.io">ES5/ES2015 등의 최신 문법을 구형 문법으로 변환시켜주는 트랜스파일러</a>를
  301. 사용하길 권장합니다.</p>
  302. </div>
  303. </div>
  304. </div>
  305. <script src="../resources/prettify.js"></script>
  306. <script src="../resources/lesson.js"></script>
  307. </body></html>