
Node.js나 Deno덕분에 JavaScript코드는 브라우저 외부에서도 실행될 수 있다.Capacitor나 React Native같은 추가 기술을 사용하면 JavaScript를 기반으로 한 모바일 앱을 만들 수 있다.현 강의에서는 브라우저에서의 자바스크립트에 집중한다.

<script> Tags<script>
alert('Hello');
</script>
<script> Import<script src="script.js"></script>
HTML과 JavaScript 코드를 분리함defer 속성<script src="assets/scripts/app.js" defer></script><script> 태그를 <body>영역의 가장 끝에 두어도 같은 효과를 적용할 수 있다.type속성의 moduel 설정<script src="assets/scripts/app.js" type="module"></script>import가 가능해진다.export한 코드를 또 다른 스크립트에 import하는 것이 가능해진다.HTML 파일에 직접 script 태그를 추가할 일이 거의 없다.
- 리액트 프로젝트는 빌드 프로세스를 사용한다.
- 이는, 작성한 코드가 브라우저에서 그대로 실행되지 않는 것을 의미한다.
- 그 대신, 브라우저에 전달되기 전에 내부적으로 코드가 수정된다.
package.json파일에서 실제 툴을 확인할 수 있다.react, react-dom을 확인할 수 있다.react-scripts: 브라우저에 전달되기 전에 뒤에서 코드를 변환하는 다양한 툴을 제공한다.
<script> 태그를 확인할 수 있다.
npm run server를 통해왜 이런 빌드 프로세스를 사용해야 할까?
JSX: JavaScript 파일에 작성된 HTML 코드

create-react-app, vite; 자동 리액트 빌드 프로세스를 포함하고 있어 별도 커스텀 설정이 필요없다.Node.js를 설치해야 한다.
- 리액트 앱에서는, 여러 파일에 코드를 분리해 관리하기 쉽게 만드는 것이 좋은 방법이다.
- 이를 위해서,
import와export키워드가 필요하다.
apiKey 변수 사용.let 키워드를 통해 변수를 생성하고, 스트링을 표현하기 위해 ''나 ""를 사용한다.export 키워드를 통해 외부에서도 해당 변수를 사용할 수 있도록 설정해준다.export let apiKey = "ndfizlvjehifz1";
import 키워드를 통해 사용한다.export할 대상의 이름을 입력하면 된다.utils.js에서 변수의 이름이 apiKey였으므로, 그 값을 입력해준다."" 안에 상대주소를 입력해준다.import/export키워드를 사용하려면 type="module"속성을 추가해야 한다.import, export 키워드가 있는 개별 파일을 모두 합쳐 하나의 큰 파일을 만든 다음 처리하므로, 해당 문법을 지원하지 않는 브라우저에서도 코드를 실행할 수 있다.import { apiKey } from "./util.js";
console.log(apiKey);
default:import/export를 사용하기 위한 또 다른 방법.export 해준다.export하는 기본값이 된다.default export만이 존재할 수 있다.export의 경우 여러개 설정 가능export할 때 사용하기 좋은 방법default 문법을 자주 사용하게 된다.// export let apiKey = "ndfizlvjehifz1";
export default "afijlzhielfjzl;vx";
export하는 default값에 이름이 할당되어 있지 않으므로, import하려는 파일에서 원하는 이름을 사용할 수 있다.import하려는 파일의 경로를 명시한다.// import { apiKey } from "./util.js";
import apiKey from "./util.js";
console.log(apiKey);
default export가 하나만 있다면, 다른 이름있는 export들과 함께 사용해도 문제가 없다.export default "afijlzhielfjzl;vx";
export let apiKey = "zvizl;fjielzh";
export let abc = "abc";
*를 사용해 자바스크립트 객체로 묶어 한번에 import할 수도 있다.as 키워드로 부여한 이름 뒤에 점을 찍어 export된 대상을 지정할 수 있다.import { apiKey } from "./util.js";
// import apiKey from "./util.js";
// import { apiKey, abc } from "./util.js";
import * as util from "./util.js";
console.log(util.apiKey);

- 📌 default
- 파일별로 하나만 가능
- import할 때에도 형식이 좀 다르다.
- 리액트에서는 하나의 컴포넌트를 export하는 일이 많아 default 사용이 빈번한 편
String: '' 나 "", ` 로 감싸진텍스트 문자.Number: 양수 혹은 음수 혹은 실수Boolean: True or False. 상태표현에 사용Null & undefined: 값이 없음을 의미undefined: 아직 값이 할당되지 않은 경우 부여되는 기본값null: 개발자에 의해 명시적으로 할당된 초기화 변수let userMessage = "Hello World!!!";
console.log(userMessage);
console.log(userMessgae);
const를 부여해두면 좋다.const userMessage = "Hello World!!!";
userMessage = "New value"; // **Error*; "userMessage" is read-only*
console.log(userMessage);
console.log(userMessgae);
conosle.log("hello" + "world"); // helloworld
===console.log(10 === 5);
// 함수 정의
function greet() {
console.log("Hello!");
}
// 함수 실행
greet();
= 연산자를 통해 기본값을 할당할 수 있다.function greetUser(userName, message = "Hello!") {
console.log(userName);
console.log(message);
}
greetUser("Max");
// Max
// Hello!
greetUser("Manuel", "Hello, what's up?");
// Manuel
// Hello, what's up?
return 키워드 사용function greetUser(userName, message = "Hello!") {
return "Hi, I am " + userName + ", " + message;
}
onClick = {() => setActiveContentIndex(0)}
function 키워드를 사용한 익명 함수export default function() {
console.log('Hello');
}
function 키워드 없이 매개변수 목록만 작성한다.export default () => {
console.log('Hello');
}
export default (userName, messgae) => {
console.log('Hello');
return userName + message;
}
(userName) => { ... } // O
userName => { ... } // O
- 함수에 매개변수가 없는 경우, 괄호를 생략할 수 없다.
() => {...}라고 작성해야 한다.- 함수가 둘 이상의 매개변수를 받는 경우, 괄호를 생략할 수 없다.
userName, userAge => { ... } // X (userName, userAge) => { ... } // O
return + {} 생략 가능number => {
return number * 3;
} // O
number => number * 3; // O
- 오류 상황
number => return number * 3;
- 이 경우 return 키워드가 생략되어야 하므로 오류가 발생한다.
number => if (number === 2) { return 5 } ;
- 이 경우 if문은 반환될 수 없으므로 오류가 발생한다.
number => { age: number }; // 객체를 반환하려고 한다.
number => ({ age: number }); // 추가 괄호를 써서 객체를 감싸준다.
키-값 쌍으로 값을 저장할 수 있다.this라는 키워드를 사용한다.const user = {
name: "Max",
age: 34,
greet() {
console.log("Hello!");
console.log(this.age)
}
};
console.log(user.name);
user.greet();
constructor 키워드를 통해 생성자 함수를 추가할 수 있다.class User {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log('Hi!');
}
}
const user1 = new User("Manuel", 35);
console.log(user1);
user1.greet();

[]를 통해 생성하고, 접근 시 []에 원하는 인덱스를 입력해 값에 접근할 수 있다.const hobbies = ["Sports", "Cooking", "Reading"];
console.log(hobbies[0]); // Sports
const userNameData = ["Max", "Schwarzmuller"];
const firstName = userNameData[0];
const lastName = userNameData[1];
const [firstName, lastName] = ["Max", "Schwarzumuller"];
console.log(firstName);
console.log(lastName);
const user = {
name: "Max",
age: 34
};
const name = user.name;
const age = user.age;
name과 age를 사용한다.:을 통해 별칭을 부여할 수 있다.const { name: userName, age } = {
name: "Max",
age: 34
};
함수 매개변수에서도 분해(디스트럭처링)를 사용할 수 있다.
예시에서는 점 표기법으로 객체의 프로퍼티에 접근하고 있다.
function setOrder(order) {
localStorage.setItem('id', order.id);
localStroage.setItem('currency', order.currency);
}
setOrder에 인수로 전달된 객체)에서 id와 currency를 꺼내어 사용한다.setOrder는 여전히 하나의 매개변수만 받고 있다.function setOrder({id, currency}) { // 디스트럭처링
localStorage.setItem('id', id);
localStroage.setItem('currency', currency);
}
setOrder({id: 5, currency: 'USD', amount:15.99}); // 1개의 매개변수
...를 사용const mergedHobbies = [...hobbies, ...newHobbies];const hobbies = ["Sports", "Cooking"];
const newHobbies = ["Reading"];
const copyHobbies = [...hobbies]; // 배열 복사
const nestedHobbies = [hobbies, newHobbies]; // 배열 중첩; 단순히 배열 하나에 두개의 배열이 들어감
const mergedHobbies = [...hobbies, ...newHobbies]; // 배열 원소들을 전개해 하나의 배열에 넣어짐.
| 배열 복사 | 배열 중첩 | 배열 병합 |
|---|---|---|
![]() | ![]() | ![]() |
const user = {
name: "Max",
age: 34
};
const extendedUser = {
isAdmin: true,
...user
};
console.log(extendedUser);
user가 전개되어 extendedUser에 추가된다....뒤의 객체의 모든 키-값 쌍을 가져와 감싸는 객체에 추가한다.
ifconst password = prompt("Your passward");
if (password === "Hello") {
console.log("Hello works");
} else if (password === "hello") {
console.log("hello works");
} else {
console.log("Access not granted.");
}
for 과 ofconst hobbies = ["Sports", "Cooking"];
for (const hobby of hobbies) {
console.log(hobby);
}
querySelector등을 사용해 요소를 직접 선택하고 조작할 수 있다.()를 작성하지 않는다.setTimeout함수는 두 개의 매개변수를 받는데, 첫 번째 입력값은 함수이다.function handleTimeout() {
console.log("Timed out!");
}
const handleTimeout2 = () => {
console.log("Timed out ... again!");
};
setTimeout(handleTimeout, 2000);
setTimeout(handleTimeout2, 3000);
setTimeout(() => {
console.log('More timing out...');
}, 4000); // 필요한 함수를 정의했을 뿐, 바로 실행되는게 아니다.
function greeter(greetFn) {
greetFn();
}
greeter(() => console.log("Hi"));
function init() {
function greet() {
console.log('Hi!');
}
greet();
}
greet(); // 실행할 수 없음.
init(); // 결과; "Hi!"
init이 greet을 호출해 한 번의 Hi!만 출력된다.
String)에도 호출할 수 있는 내장 메서드가 있다.concat메서드를 사용해 다른 스트링을 연결하면, 기존 스트링을 수정하는 대신 새 스트링이 생성된다.let userMessage = 'Hello!';
userMessage = 'Hello there!'; // 기존에 메모리에 저장된 스트링은 삭제된다.
userMessage = userMessage.concat('!!!');
const로 선언된 배열 hobbies를 수정할 수 있다. (push를 통해 값을 넣었다.)const는 수정할 수 없음을 의미하지만, 엄밀히 말하자면 변수를 덮어쓸 수 없다는 것을 의미한다.const를 사용하면 =연산자를 통해 새 값을 할당할 수 없다.const hobbies = ["Sprots", "Cooking"];
hobbies = []; // ** error
hobbies.push("Working");
console.log(hobbies);