데이터 유형 장에서 알 수 있듯이 JavaScript에는 8가지 데이터 유형이 있습니다. 그 중 7개는 "원시"라고 불립니다. 왜냐하면 그 값에는 단 하나의 항목(문자열, 숫자 등)만 포함되어 있기 때문입니다.
대조적으로, 객체는 다양한 데이터와 더 복잡한 엔터티의 키 입력 컬렉션을 저장하는 데 사용됩니다. JavaScript에서 객체는 언어의 거의 모든 측면에 침투합니다. 그러므로 우리는 다른 곳으로 깊이 들어가기 전에 먼저 그것들을 이해해야 합니다.
선택적인 속성 목록과 함께 그림 괄호 {…}
사용하여 객체를 생성할 수 있습니다. 속성은 "키:값" 쌍입니다. 여기서 key
는 문자열("속성 이름"이라고도 함)이고 value
무엇이든 될 수 있습니다.
서명된 파일이 있는 캐비닛으로 개체를 상상할 수 있습니다. 모든 데이터 조각은 키에 의해 파일에 저장됩니다. 이름으로 파일을 찾거나 파일을 추가/제거하는 것은 쉽습니다.
빈 개체("빈 캐비닛")는 다음 두 구문 중 하나를 사용하여 생성할 수 있습니다.
사용자 = 새 개체()를 보자; // "객체 생성자" 구문 사용자 = {}로 두십시오; // "객체 리터럴" 구문
일반적으로 그림 대괄호 {...}
가 사용됩니다. 해당 선언을 객체 리터럴 이라고 합니다.
일부 속성을 "키: 값" 쌍으로 즉시 {...}
에 넣을 수 있습니다.
let user = { // 객체 name: "John", // "name" 키로 값 "John" 저장 age: 30 // "age" 키로 저장 값 30 };
속성에는 콜론 ":"
앞에 키("이름" 또는 "식별자"라고도 함)가 있고 그 오른쪽에 값이 있습니다.
user
개체에는 두 가지 속성이 있습니다.
첫 번째 속성의 이름은 "name"
이고 값은 "John"
입니다.
두 번째 항목의 이름은 "age"
이고 값은 30
입니다.
결과 user
개체는 "이름"과 "나이"라는 레이블이 붙은 두 개의 서명된 파일이 있는 캐비닛으로 상상할 수 있습니다.
언제든지 파일을 추가, 제거 및 읽을 수 있습니다.
속성 값은 점 표기법을 사용하여 액세스할 수 있습니다.
// 객체의 속성 값을 가져옵니다. 경고(사용자.이름); // 존 경고(사용자.나이); // 30
값은 모든 유형이 될 수 있습니다. 부울 값을 추가해 보겠습니다.
user.isAdmin = 사실;
속성을 제거하려면 delete
연산자를 사용할 수 있습니다.
user.age 삭제;
여러 단어로 된 속성 이름을 사용할 수도 있지만 다음과 같이 따옴표로 묶어야 합니다.
사용자 = { 이름: "존", 나이: 30, "likesbirds": true // 여러 단어로 된 속성 이름을 인용해야 합니다. };
목록의 마지막 속성은 쉼표로 끝날 수 있습니다.
사용자 = { 이름: "존", 나이: 30, }
이를 "후행" 또는 "매달기" 쉼표라고 합니다. 모든 선이 유사해지기 때문에 속성 추가/제거/이동이 더 쉬워집니다.
여러 단어 속성의 경우 점 액세스가 작동하지 않습니다.
// 구문 오류가 발생합니다. user.likes 새 = true
JavaScript는 그것을 이해하지 못합니다. 이는 우리가 user.likes
처리한다고 생각하고 예상치 못한 birds
발견하면 구문 오류를 제공합니다.
점을 사용하려면 키가 유효한 변수 식별자여야 합니다. 이는 공백을 포함하지 않고, 숫자로 시작하지 않으며, 특수 문자를 포함하지 않음을 의미합니다( $
및 _
허용).
모든 문자열에 사용할 수 있는 대체 "대괄호 표기법"이 있습니다.
사용자 = {}로 두십시오; // 세트 user["새를 좋아함"] = true; // 얻다 Alert(user["새를 좋아합니다"]); // 진실 // 삭제 사용자 삭제["새를 좋아합니다"];
이제 모든 것이 괜찮습니다. 대괄호 안의 문자열은 적절하게 인용되어 있습니다(어떤 유형의 인용문이라도 가능).
또한 대괄호는 다음과 같이 변수에서 리터럴 문자열이 아닌 표현식의 결과로 속성 이름을 얻는 방법을 제공합니다.
키 = "새를 좋아함"; // user["likesbirds"]와 동일 = true; 사용자[키] = true;
여기서 변수 key
런타임에 계산되거나 사용자 입력에 따라 달라질 수 있습니다. 그런 다음 이를 사용하여 속성에 액세스합니다. 이는 우리에게 상당한 유연성을 제공합니다.
예를 들어:
사용자 = { 이름: "존", 나이: 30 }; let key = 프롬프트("사용자에 대해 무엇을 알고 싶으십니까?", "name"); // 변수로 접근 경고( 사용자[키] ); // John("이름"을 입력한 경우)
점 표기법은 비슷한 방식으로 사용할 수 없습니다.
사용자 = { 이름: "존", 나이: 30 }; 키 = "이름"; 경고( user.key ) // 정의되지 않음
객체를 생성할 때 객체 리터럴에 대괄호를 사용할 수 있습니다. 이를 계산된 속성 이라고 합니다.
예를 들어:
let Fruit = 프롬프트("어떤 과일을 살까요?", "사과"); 가방 = { [fruit]: 5, // 속성 이름은 변수 Fruit에서 가져옵니다. }; 경고(bag.apple); // 과일="사과"인 경우 5
계산된 속성의 의미는 간단합니다. [fruit]
는 속성 이름이 fruit
에서 가져와야 함을 의미합니다.
따라서 방문자가 "apple"
입력하면 bag
{apple: 5}
가 됩니다.
기본적으로 이는 다음과 동일하게 작동합니다.
let Fruit = 프롬프트("어떤 과일을 살까요?", "사과"); 가방 = {}을 보자; // 과일 변수에서 속성 이름을 가져옵니다. 가방[과일] = 5;
…하지만 더 좋아 보이는군요.
대괄호 안에 더 복잡한 표현식을 사용할 수 있습니다.
과일 = '사과'라고 하자; 가방 = { [과일 + '컴퓨터']: 5 // bag.appleComputers = 5 };
대괄호는 점 표기법보다 훨씬 더 강력합니다. 모든 속성 이름과 변수를 허용합니다. 하지만 쓰기가 더 번거롭기도 합니다.
그래서 대부분의 경우 속성 이름이 알려져 있고 단순할 때 점이 사용됩니다. 그리고 좀 더 복잡한 것이 필요하면 대괄호로 전환합니다.
실제 코드에서는 기존 변수를 속성 이름의 값으로 사용하는 경우가 많습니다.
예를 들어:
function makeUser(이름, 나이) { 반품 { 이름: 이름, 나이: 나이, // ...다른 속성 }; } let user = makeUser("John", 30); 경고(사용자.이름); // 존
위의 예에서 속성은 변수와 동일한 이름을 갖습니다. 변수에서 속성을 만드는 사용 사례는 매우 일반적이므로 이를 더 짧게 만드는 특별한 속성 값 약어가 있습니다.
name:name
대신 다음과 같이 name
쓸 수 있습니다.
function makeUser(이름, 나이) { 반품 { 이름, // 이름과 동일: 이름 나이, // 나이와 동일: 나이 // ... }; }
동일한 객체에서 일반 속성과 속기를 모두 사용할 수 있습니다.
사용자 = { 이름, // 이름:이름과 동일 나이: 30 };
이미 알고 있듯이 변수는 "for", "let", "return" 등과 같은 언어 예약어 중 하나와 동일한 이름을 가질 수 없습니다.
그러나 객체 속성의 경우 이러한 제한이 없습니다.
// 이 속성은 괜찮습니다. obj = {라고 놔두세요 대상: 1, 하자: 2, 반환: 3 }; 경고(obj.for + obj.let + obj.return ); // 6
즉, 속성 이름에는 제한이 없습니다. 문자열이나 기호(나중에 다룰 식별자의 특수 유형)일 수 있습니다.
다른 유형은 자동으로 문자열로 변환됩니다.
예를 들어, 숫자 0
속성 키로 사용될 때 문자열 "0"
이 됩니다.
obj = {라고 놔두세요 0: "테스트" // "0": "테스트"와 동일 }; // 두 경고 모두 동일한 속성에 액세스합니다(숫자 0은 문자열 "0"으로 변환됨). 경고( obj["0"] ); // 시험 경고(obj[0]); // 테스트(동일한 속성)
__proto__
라는 특수 속성에 사소한 문제가 있습니다. 객체가 아닌 값으로 설정할 수 없습니다.
obj = {}로 놔두세요; obj.__proto__ = 5; //번호 할당 경고(obj.__proto__); // [object Object] - 값이 객체인데 의도한 대로 작동하지 않았습니다.
코드에서 볼 수 있듯이 기본 5
에 대한 할당은 무시됩니다.
우리는 다음 장에서 __proto__
의 특별한 성격을 다루고 그러한 동작을 수정하는 방법을 제안할 것입니다.
다른 많은 언어와 비교하여 JavaScript 개체의 주목할만한 특징은 모든 속성에 액세스할 수 있다는 것입니다. 속성이 존재하지 않아도 오류가 발생하지 않습니다!
존재하지 않는 속성을 읽으면 undefined
반환됩니다. 따라서 속성이 존재하는지 쉽게 테스트할 수 있습니다.
사용자 = {}로 두십시오; 경고( user.noSuchProperty === 정의되지 않음); // true는 "해당 속성이 없음"을 의미합니다.
이를 위한 특수 연산자 "in"
도 있습니다.
구문은 다음과 같습니다.
객체의 "키"
예를 들어:
let user = { 이름: "John", 나이: 30 }; 경고(사용자의 "나이" ); // true, user.age가 존재합니다. 경고(사용자의 "blabla"); // false, user.blabla가 존재하지 않습니다.
in
왼쪽에는 속성 이름이 있어야 합니다. 이는 일반적으로 인용된 문자열입니다.
따옴표를 생략하면 변수에 테스트할 실제 이름이 포함되어야 함을 의미합니다. 예를 들어:
사용자 = { 연령: 30 }; 키 = "나이"; 경고(사용자의 키); // true, "age" 속성이 존재합니다.
in
연산자가 존재하는 이유는 무엇입니까? undefined
과 비교하면 충분하지 않나요?
글쎄요, 대부분의 경우 undefined
과의 비교는 잘 작동합니다. 하지만 실패하는 특별한 경우가 있지만 "in"
올바르게 작동합니다.
객체 속성이 존재하지만 undefined
저장하는 경우입니다.
obj = {라고 놔두세요 테스트: 정의되지 않음 }; 경고(obj.test); // 정의되지 않았으므로 - 그런 속성이 없나요? 경고( obj의 "테스트" ); // true, 속성이 존재합니다!
위 코드에는 기술적으로 obj.test
속성이 존재합니다. 따라서 in
연산자가 올바르게 작동합니다.
이와 같은 상황은 매우 드물게 발생합니다. undefined
명시적으로 할당하면 안 되기 때문입니다. 우리는 대부분 "알 수 없음" 또는 "빈" 값에 대해 null
사용합니다. 따라서 in
연산자는 코드에서 이국적인 손님입니다.
객체의 모든 키를 탐색하기 위해 특별한 형태의 루프가 있습니다: for..in
. 이는 이전에 연구한 for(;;)
구문과는 완전히 다른 것입니다.
구문:
for(객체의 키) { //객체 속성 중 각 키에 대한 Body를 실행합니다. }
예를 들어 user
의 모든 속성을 출력해 보겠습니다.
사용자 = { 이름: "존", 나이: 30, isAdmin: 사실 }; for (사용자 키 입력) { // 키 경고( 키 ); // 이름, 나이, isAdmin // 키 값 경고( 사용자[키] ); // John, 30세, 참 }
모든 "for" 구문을 사용하면 여기서 let key
와 같이 루프 내부에 루프 변수를 선언할 수 있습니다.
또한 여기에서는 key
대신 다른 변수 이름을 사용할 수도 있습니다. 예를 들어 "for (let prop in obj)"
도 널리 사용됩니다.
물건은 주문되어 있나요? 즉, 객체를 반복하면 추가된 순서대로 모든 속성을 얻을 수 있습니까? 우리는 이것에 의존할 수 있습니까?
짧은 대답은 다음과 같습니다. "특별한 방식으로 정렬됩니다.": 정수 속성은 정렬되고 다른 속성은 생성 순서에 따라 나타납니다. 자세한 내용은 다음과 같습니다.
예를 들어, 전화 코드가 포함된 객체를 생각해 보겠습니다.
코드 = { "49": "독일", "41": "스위스", "44": "영국", // .., "1": "미국" }; for (코드를 코드로 놔두세요) { 경고(코드); // 1, 41, 44, 49 }
개체는 사용자에게 옵션 목록을 제안하는 데 사용될 수 있습니다. 주로 독일 사용자를 대상으로 하는 사이트를 만들고 있다면 아마도 49
첫 번째 사이트가 되기를 원할 것입니다.
그러나 코드를 실행하면 완전히 다른 그림이 나타납니다.
미국(1)이 먼저 갑니다.
스위스(41) 등이 그 뒤를 이었습니다.
전화 코드는 정수이므로 오름차순으로 정렬됩니다. 그래서 우리는 1, 41, 44, 49
를 봅니다.
정수 속성? 그게 뭐야?
여기서 "정수 속성"이라는 용어는 변경 없이 정수로 변환될 수 있는 문자열을 의미합니다.
따라서 "49"
는 정수 속성 이름입니다. 정수로 변환하고 그 반대로 변환해도 여전히 동일하기 때문입니다. 그러나 "+49"
와 "1.2"
다음이 아닙니다.
// Number(...)는 명시적으로 숫자로 변환됩니다. // Math.trunc는 소수 부분을 제거하는 내장 함수입니다. Alert( String(Math.trunc(Number("49"))) ); // "49", 동일, 정수 속성 경고( String(Math.trunc(Number("+49"))) ); // "49", 동일하지 않음 "+49" ⇒ 정수 속성 아님 경고( String(Math.trunc(Number("1.2"))) ); // "1", 동일하지 않음 "1.2" ⇒ 정수 속성 아님
...반면에 키가 정수가 아닌 경우 생성 순서대로 나열됩니다. 예를 들면 다음과 같습니다.
사용자 = { 이름: "존", 성 : "스미스" }; 사용자 나이 = 25; // 하나 더 추가 // 정수가 아닌 속성은 생성 순서에 나열됩니다. for (사용자의 소품을 보자) { 경고(prop); // 이름, 성, 나이 }
따라서 전화 코드 문제를 해결하려면 코드를 정수가 아닌 것으로 만들어 "속임수"를 사용할 수 있습니다. 각 코드 앞에 더하기 "+"
기호를 추가하는 것으로 충분합니다.
이와 같이:
코드 = { "+49": "독일", "+41": "스위스", "+44": "영국", // .., "+1": "미국" }; for (코드를 코드로 놔두세요) { 경고( +코드 ); // 49, 41, 44, 1 }
이제 의도한 대로 작동합니다.
객체는 몇 가지 특별한 기능을 가진 연관 배열입니다.
여기에는 다음과 같은 속성(키-값 쌍)이 저장됩니다.
속성 키는 문자열 또는 기호(일반적으로 문자열)여야 합니다.
값은 모든 유형이 될 수 있습니다.
속성에 액세스하려면 다음을 사용할 수 있습니다.
점 표기법: obj.property
.
대괄호 표기 obj["property"]
. 대괄호를 사용하면 obj[varWithKey]
와 같은 변수에서 키를 가져올 수 있습니다.
추가 연산자:
속성을 삭제하려면 delete obj.prop
.
주어진 키를 가진 속성이 존재하는지 확인하려면: "key" in obj
.
객체를 반복하려면: for (let key in obj)
루프.
이 장에서 우리가 공부한 것을 "일반 객체" 또는 간단히 Object
라고 합니다.
JavaScript에는 다른 종류의 객체도 많이 있습니다.
정렬된 데이터 컬렉션을 저장하는 Array
,
날짜와 시간에 대한 정보를 저장하는 Date
,
오류에 대한 정보를 저장하는 Error
.
…등.
그것들은 우리가 나중에 연구할 특별한 특징을 가지고 있습니다. 때때로 사람들은 "배열 유형" 또는 "날짜 유형"과 같은 것을 말하지만 공식적으로는 자체 유형이 아니라 단일 "객체" 데이터 유형에 속합니다. 그리고 그들은 그것을 다양한 방식으로 확장합니다.
JavaScript의 객체는 매우 강력합니다. 여기서 우리는 정말 거대한 주제의 표면만을 긁어보았습니다. 우리는 튜토리얼의 추가 부분에서 개체를 사용하여 긴밀하게 작업하고 개체에 대해 자세히 알아볼 것입니다.
중요도: 5
각 작업에 대해 한 줄씩 코드를 작성합니다.
빈 개체 user
생성합니다.
값이 John
인 속성 name
추가합니다.
값이 Smith
속성 surname
추가합니다.
name
값을 Pete
로 변경합니다.
개체에서 속성 name
제거합니다.
사용자 = {}로 두십시오; user.name = "존"; user.surname = "스미스"; user.name = "피트"; 사용자 이름 삭제;
중요도: 5
객체에 속성이 없으면 true
반환하고 그렇지 않으면 false
를 반환하는 함수 isEmpty(obj)
를 작성하세요.
다음과 같이 작동해야 합니다.
일정을 보자 = {}; 경고( isEmpty(일정) ); // 진실 일정["8:30"] = "일어나다"; 경고( isEmpty(일정) ); // 거짓
테스트를 통해 샌드박스를 엽니다.
객체를 반복하고 하나 이상의 속성이 있으면 즉시 return false
.
함수 isEmpty(obj) { for(obj에 키를 넣음) { // 루프가 시작되면 속성이 있습니다. 거짓을 반환; } 사실을 반환; }
샌드박스에서 테스트를 통해 솔루션을 엽니다.
중요도: 5
우리 팀의 급여를 저장하는 객체가 있습니다.
급여 = { 존: 100, 앤: 160, 피트: 130 }
모든 급여를 합산하여 변수 sum
에 저장하는 코드를 작성하세요. 위 예에서는 390
이어야 합니다.
salaries
비어 있으면 결과는 0
이어야 합니다.
급여 = { 존: 100, 앤: 160, 피트: 130 }; 합계 = 0으로 둡니다. for (급여를 입력하자) { 합계 += 급여[키]; } 경고(합계); // 390
중요도: 3
obj
의 모든 숫자 속성 값에 2
곱하는 함수 multiplyNumeric(obj)
를 만듭니다.
예를 들어:
// 통화 전 메뉴 = { 폭: 200, 높이: 300, title: "내 메뉴" }; MultiplyNumeric(메뉴); // 호출 후 메뉴 = { 폭: 400, 높이: 600, title: "내 메뉴" };
multiplyNumeric
은 아무것도 반환할 필요가 없습니다. 객체를 그 자리에서 수정해야 합니다.
PS 여기에서 숫자를 확인하려면 typeof
사용하세요.
테스트를 통해 샌드박스를 엽니다.
함수 곱셈숫자(obj) { for(obj에 키를 넣음) { if (typeof obj[key] == '숫자') { obj[키] *= 2; } } }
샌드박스에서 테스트를 통해 솔루션을 엽니다.