모던 자바스크립트 Deep Dive를 통해 진행중인 자바스크립트 스터디 3주차 이번주 내가 발표한 내용은 DOM이다. 그 중에서도 여러 노드들의 차이점, getter를 가지는 프로퍼티, getter와 setter를 함께 가지는 프로퍼티 등을 구분하여 발표하였다. 구분만 하고 보니 내용이 적은 느낌적인 느낌느낌... 책을 보고 정리한거지만 제 생각이 들어가면서 잘못된 부분이 있을 수도 있으니 혹시 이상한 부분이 있다면 댓글 남겨주세요
HTMLCollection VS NodeList
HTMLCollection
NodeList
DOM API가 여러 개의 결과 값을 반환하기 위한 DOM 컬렉션 객체 유사 배열 객체이며 이터러블이다 스프레드 문법을 사용하여 배열로 변환 가능
노드 객체의 상태 변화를 실시간으로 반영한다 살아 있는 객체(live) 실시간으로 객체의 상태를 변경하여 반영하여서 for 문 순회시 주의해야 한다 getElementsByTagName getElementsByClassName
실시간으로 노드 객체의 상태 변경을 반영하지 않는다 과거 정적 상태를 유지하는 객체(non-live) childNodes 프로퍼티가 변환하는 NodeList객체는 Live 객체로 동작하므로 주의해야한다 querySeletorAll
HTML 어트리뷰트 VS DOM 프로퍼티
HTML 어트리뷰트
DOM 프로퍼티
HTML 요소는 여러 개의 어트리뷰트를 가질 수 있다 모든 어트리뷰트 노드의 참조는 유사 배열 객체이자 이터러블인 NameNodeMap개게에 담겨서 요소 노드의 attributes 프로퍼티에 저장된다 HTML 초기 상태를 지정한다 HTML 어트리뷰트 값은 HTML 초기 상태를 의미하며 변하지 않는다
HTML 어트리뷰트에 대응하는프로퍼티 HTML 어트리뷰트 값을 초기값으로 가진다 setter와 getter 모두 존재하는 접근자 프로퍼티로 참조와 변경이 가능하다 요소 노드의 최신 상태는 DOM 프로퍼티가 관리한다
getter 프로퍼티와 getter and setter 프로퍼티
getter
getter and setter
참조한 가능한 읽기 전용 접근자 프로퍼티 읽기 전용 접근자 프로퍼티에 값을 할당하면 아무런 에러 없이 무시된다
스파로스 아카데미에서 진행중인 Javascript 스터디 2주차 모던 자바스크립트 Deep Dive를 통해 진행중 이번주 내가 발표한 내용은 생성자 함수에 의한 객체 생성, 함수와 일급 객체 부분이다. 저번주에 비해 난이도가 확 올라간 느낌! 발표를 진행하면서 질문 들어오면 대답 못할까봐 걱정 많이 했다. (질문이 안들어왔다) 책을 보고 정리한거지만 제 생각이 들어가면서 잘못된 부분이 있을 수 있습니당.......,,,,,,\(º □ º l|l)/ 혹시 있다면 댓글 남겨주세요
객체 생성 방법
객체 리터럴
Object 생성자 함수
생성자 함수
Object.create 메서드
클래스(ES6)
생성자 함수에 의한 객체 생성
Object 생성자 함수
new 연산자와 함께 Object 생성자 함수를 호출하면 빈 객체를 생성하여 반환
Object 생성자 함수를 사용해 객체를 생성하는 방식은 특별한 이유가 없다면 그다지 유용하지 않아 보임
생성자 함수
생성자 함수 방식의 장점
생성자 함수에 의한 객체 생성 방식은 객체를 생성하기 위한 템플릿처럼 생성자 함수를 사용하여 프로퍼티 구조가 동일한 객체 여러 개를 간편하게 생성할 수 있음
마치 붕어빵 틀을 사용하는 것 처럼 비슷한 모양의 객체 생성 가능
팥이 든 붕어빵... 슈크림이 든 붕어빵...
New 연산자와 함께 호출하면 생성자 함수로 동작한다
생성자 함수의 인스턴스 생성 과정
생성자 함수의 역할은 프로퍼티 구조가 동일한 인스턴스를 생성하기 위한 템플릿으로서 동작하여 인스턴스를 생성하는 것과 생성된 인스턴스를 초기화(인스턴스 프로퍼티 추가 및 초기값 할당)하는 것이다.
인스턴스 생성과 this 바인딩 -> 인스턴스 초기화 -> 인스턴스 반환
내부 메서드 [[Call]]과 [[Construct]]
함수는 객체이므로 일반 객체와 동일하게 동작할 수 있다.
하지만 함수는 일반 객체와 다른데, 일반 객체는 호출할 수 없지만 함수는 호출할 수 있다.
함수가 일반 함수로서 호출되면 함수 객체의 내부 메서드 [[Call]]이 호출되고 new연산자와 함께 생성자 함수로서 호출되면 내부 메서드 [[Construct]]가 호출된다.
constructor와 non-constructor의 구분
Constructor
non-constructor
[[Construct]]를 가지는 함수 객체 일반 함수 또는 생성자 함수로서 호출할 수 있는 객체
[[Construct]]를 가지지 않는 함수 객체 일반 함수로서만 호출할 수 있는 객체
함수 선언문 함수 표현식 클래스
메서드 화살표 함수
new 연산자
new연산자와 함께 함수를 호출하면 해당 함수는 생성자 함수로 동작
new 연산자와 함께 호출하는 함수는 non-constructor가 아닌 constructor이어야 한다.
함수와 일급 객체
일급객체
일급객체란
무명의 리터럴로 생성할 수 있다. 즉, 런타임에 생성이 가능하다.
변수나 자료구조(객체, 배열 등)에 저장할 수 있다.
함수의 매개변수에 전달할 수 있다.
함수의 반환값으로 사용할 수 있다.
자바스크립트의 함수는 일급 객체
함수 객체의 프로퍼티
arguments 프로퍼티
arguments 프로퍼티 값은 arguments 객체다
매개변수 개수를 확정할 수 없는 가변 인자 함수를 구현할 때 유용
Caller 프로퍼티
비표준 프로퍼티
함수 자신을 호출한 함수를 가리킨다
참고로만 알아두고 지나쳐도 좋다
length 프로퍼티
함수를 정의할 때 선언한 매개변수의 개수를 가리킨다
function foo() {}
console.log(foo.length); //0
function bar(x){}
console.log(bar.length); //1
function sua(x,y,z){}
console.log(sua.length); //3
name 프로퍼티
함수 이름을 나타낸다
// 기명 함수 표현식
var nameFunc = function foo(){}
console.log(namedFunc.name); //foo
// 익명 함수 표현식
var anonymousFunc = functon() {}
console.log(anonymousFunc.name) // anonymousFunc
// 함수 선언문
function bar() {}
console.log(bar.name) // bar
__proto__접근자 프로퍼티
[[Prototype]]내부 슬롯이 가리키는 프로토타입 객체에 접근하기 위해 사용하는 접근자 프로퍼티
접근자 프로퍼티를 통해 간접적으로 프로토타입 객체에 접근할 수 있다
prototype 프로퍼티
constructor만이 소유하는 프로퍼티
생성자 함수로 호출할 수 없는 non-constructor에는 prototype프로퍼티가 없다.
' - ' ' * ' ' / ' 등의 산술 연산자는 평가를 위해 산술 연산자의 피연산자 중에서 숫자 타입이 아닌 피연산자를 숫자 타입으로 암묵적 타입 변환한다.
비교 연산자는 불리언 값을 만든다
'1' > 0 // 숫자형으로 변환되어 true를 반환
+ 단항 연산자는 숫자 타입이 아니면 숫자 타입의 값으로 타입 변환한다
+'' // 0
+'0' // 0
+'2' // 2
불리언 타입으로의 변환
Truthy 참으로 평가되는 값
Falsy 거짓으로 평가되는 값
Falsy가 아닌 모든 값
false undefined null 0, -0 NaN ''
명시적 타입 변환
- 개발자의 의도에 따라 명시적으로 타입을 변환한다
표준 빌트인 생성자 함수를 new 연산자 없이 호출하는 방법
빌트인 메서드를 사용하는 방법
암묵적 타입 변환을 이용하는 방법(아마 암묵적 변환을 사용하는 상황 자체가 개발자가 의도적으로 사용하기 때문에 암묵적이 명시적 타입 변환의 한 방법으로 들어가지 않았나,,,하는 마이 띵킹)
문자열 타입으로 변환
1. String 생성자 함수를 new 연산자 없이 호출 -> String(1)
2. Object.prototype.toString 메서드를 사용 -> (1).toString();
3. 문자열 연결 연산자 사용 -> 1 + ''
숫자형 타입으로 변환
1. Number 생성자 함수를 new 연산자 없이 호출하는 방법 -> Number('1')
2. parseInt, parseFloat 함수를 사용하는 방법(문자열만 숫자 타입으로 변환 가능) -> parseInt('1')
3. + 단항 산술 연산자를 이용하는 방법 -> + '0'
4. * 산술 연산자를 이용하는 방법 -> '1' * 1
불리언 타입으로 변환
1. Boolean 생성자 함수를 new 연산자 없이 호출하는 방법 -> Boolean('x')
2. ! 부정 논리 연산라를 두 번 사용하는 방법 -> !!'x'
단축 평가
논리 연산자를 사용해 단축 평가가 가능하다
단축 평가 표현식
평가 결과
true || anything
true
false || anything
anything
frue && anything
anything
false && anything
false
const getName = (person) => {
const name = person && person.name;
// 2. 논리 곱은 두 값이 모두 true가 되어야 true를
// 반환하기 때문에 false 로 값이 반환되지 않습니다.
return name || "객체가 아닙니다";
// 3. 그럼 현재 name에는 값이 들어있지 않은 상태입니다
// 논리 곱은 둘 중 하나만 true여도 true로
// 해당 값을 반환합니다. name 이 falsy이므로 false로 인지,
// 뒤의 값이 true인지 확인합니다. 뒤의 값은 "안 빈 문자열"
// 이므로 truthy 값 입니다. 그러므로 해당 값을 반환합니다.
};
let person = "";
// 1. 다음과 같이 person에 빈 문자열이 들어간 경우에
// 1. 혹은 { age: 26 } 과 같이 person.name 이 아닌값이라도
const name = getName(person);
console.log(name);
객체 리터럴
원시 값을 제외한 나머지 자바스크립트를 구성하는 거의 모든 것은 객체이다.(원시 값 제외)
객체의 집합으로 프로그램을 표현하는 것을 객체지향 프로그래밍이라 한다.
객체는 변경 하능한 값이다.
자바스크립트는 클래스 기반 객체지향 언어와는 달리 다양한 객체 생성 방법을 지원한다.
객체 리터럴
Object 생성자 함수
생성자 함수
Object.create 메서드
클래스(ES6)
객체 리터럴은...
단순히 {} 중괄호를 이용하여 객체를 만들 수 있다
중괄호 안에 프로퍼티와메서드를채워넣기만 하면 된다! 간단!
프로퍼티
'키'와 '값'으로 구성된다
접근법
마침표 접근법
대괄호 표기법
console.log(person.name);
console.log(person['name'])
대괄호 표기접으로 접근하는 경우 플퍼티 키는 반드시 따옴표로 감싼 문자열이어야 한다.
// 프로퍼티를 수정하는 것은 person이라는 상수 자체를 수정하는
// 행위가 아니기 때문에 수정이 된다
const person = {
name: "박수아",
age: 26
};
// 프로퍼티 추가하기
person.location = "한국";
person["gender"] = "여성";
console.log(person);
// 프로퍼티 수정하기
person.name = "park su ah";
person["age"] = 24;
console.log(person);
// 프로퍼티 삭제하기
// 메모리에서 지워지지는 않는다.
delete person.age;
delete person["name"];
console.log(person);
// 메모리에서도 지우는 방법
person.location = null;
console.log(person);
메소드
함수는 값으로 취급할 수 있기 때문에 프로퍼티 값으로 사용할 수 있다.
구분을 위해서 함수는 메소드라고 부른다.
원시 값과 객체의 비교
원시 값
원시 값은 변경 불가능한 값이다. 읽기전용 값이다.
변수 값을 변경하기 위해 원시 값을 재할당하면 새로운 메모리 공간을 확보하고 재할당한 값을 저장한 후, 변수가 참조하던 메모리 고간의 주소를 변경한다. 이러한 특성을 불변성이라 한다.
객체
객체는 프로퍼티의 개수가 정해져 있지 않으며, 동적으로 추가되고 삭제할 수 있다 또한 프로퍼티의 값에도 제약이 없다. 따라서 객체는 원시 값과 같이 확보해야 할 메모리 공간의 크기를 사전에 정해 둘 수 없다.
변경 가능한 값이다.
객체는 크기가 매우 클 수도 있고, 원시 값처럼 크기가 일정하지도 않으며, 프로퍼티 값이 객체일 수도 있어서 복사해서 생성하는 비용이 많이 든다.
따라서 메모리를 효율적으로 사용하고 객체를 복사해 생성하는 비용을 절약하기 위해 객체는 변경 가능한 값으로 설계한다.
부작용으로 여러 개의 식별자가 하나의 객체를 공유할 수 있다.
const person = {
name : "suah",
age : 26
}
const human = person
console.log(person) // {name:"suah", age:26}
console.log(human) // {name:"suah", age:26}
const person = {
name : "suah",
age : 26
}
const human = person
person.name = "park suah"
console.log(person) // {name:"park suah", age:26}
console.log(human) // {name:"park suah", age:26}