728x90
1. 객체 생성
- 종류 2가지
- 빈 객체 생성한 후, 멤버(속성, 함수) 추가
- 객체의 생성과 동시에 멤버 추가
// 1. 객체의 생성방법
const person = {};
// property 추가
person.firstName = "join";
console.log(typeof person); // object
// 2. 객체 생성 + 초기화
const myObject = {
firstName: "join",
};
console.log(typeof myObject); // object
2. 생성자로 객체 생성
- 생성자를 정의하면 객체를 편리하게 생성
- 해당 객체 호출시 객체 이름 { property, function} 출력
- 하지만 type은 object
- 주의
- 생성자라고 해도 결국에는 function일 뿐이다.
- 해당 function을 사용을 할 때 new를 사용하면 해당 function이 생성자로 작동을 하게 된다.
- 그래서 function 중 생성자로 사용하고 싶은 것은 첫 char을 대문자로 작성을 한다. - 전통
- this
- 객체 내부 : 객체 자신
- 해당 생성자로 생성한 객체는 주소를 가진다.
- this는 해당 객체 주소이다.
// 생성자로 객체 생성
function Person(name, age) {
this.name = name;
this.age = age;
}
// 차이점
const myObject = { firstName: "join" };
console.log(myObject); // { firstName: 'join' }
console.log(typeof myObject); // object
const obj = new Person("a", 12);
console.log(obj); // Person { name: 'a', age: 12 } -- 앞에 Person이 붙음
console.log(typeof obj); // object
const obj2 = Person("a", 21); // window의 property가 된다.
- 각 객체별로 모듈화가 되어있다. 서로 공유하지 않는다.
3. 객체의 속성(멤버) 삭제
- delete연산자로 객체의 속성 삭제
- 물려받은 속성은 삭제 불가
- 생성자에 설정한 멤버 삭제 불가
- 생성자를 이용해서 생성한 인스턴스의 멤버는 삭제 가능
function Person(name, age) {
this.name = name;
this.age = age;
}
const obj = new Person("a", 12); // Person { name: 'a', age: 12 }
// instance 멤버 삭제
delete obj.name;
console.log(obj.toString()); // name: undefined, age : 12
// 해당 class 멤버 삭제 시도
delete Person.name; // 생성자 속성 제거 불가
console.log(obj.toString()); // params에 name 유지되어있다.
4. instanceof
- 기본형은 당연히 사용안됨
- 객체일 때만 사용 가능
- 생성자로 생성한 인스턴스는 해당 생성자 명의 객체 타입을 사용할 수 있다.
5. prototype, __proto__, constructor
- prototype
- 함수 객체의 property 중 하나로, 해당 함수를 생성자로 사용하여 만든 객체들이 공통으로 사용할 수 있는 property와 메소드를 저장하는 객체
- 생성자 함수를 정의할 때, 그 생성자로부터 만들어진 객체들이 공유할 property나 메소드를 추가하기 위한 용도로 사용
- property와 메소드는 생성자 함수가 생성될 때마다 한 번만 생성되고, 이를 상속받은 객체들은 모두 이 property와 method를 사용할 수 있습니다.
- __proto__는 모든 객체가 가지고 있는 숨겨진 property 중 하나
- property는 객체가 생성될 때 해당 객체의 생성자 함수의 prototype을 참조
- 즉, 객체가 생성된 후에 해당 객체와 생성자 함수의 prototype 사이에 연결을 만들어 준다. 따라서, __proto__를 이용해 상속을 구현할 수 있다.
- 간단하게 말하면, prototype은 생성자 함수가 가지고 있는 객체이고, __proto__는 해당 객체가 가지고 있는 prototype 객체를 참조하는 property이다. prototype은 함수 객체에서만 사용되는 것이고, __proto__는 모든 객체에서 사용됩니다.
- 생성자의 prototype을 이용한 함수 공유
function Person(name, age) {
this.name = name;
this.age = age;
}
var obj = new Person("david", 10);
var obj2 = new Person("wendy", 20);
// prototype function 생성
Person.prototype.getName = function () {
return this.name;
};
// prototype property 생성
Person.prototype.abc = "123";
// prototype property 사용
console.log(obj.abc);
console.log(obj2.abc);
// prototype method 사용
console.log(obj.getName());
console.log(obj2.getName());
console.dir(Person); // prototype property 생성 - 내부에 __proto__, constructor 존재
console.dir(obj); // 내부에 __proto__ 존재
6. this
- this는 기본적으로 함수를 호출하는 객체를 의미
- 전역 범위에서 this는 window를 가리킨다.
function Person(name, age) {
this.name = name;
this.age = age;
}
const obj = new Person("a", 12); // Person { name: 'a', age: 12 }
const obj2 = Person("b", 2); // new를 사용하지 않아서 window객체의 멤버로 들어간다.
const myObject = {
firstName: "join",
};
// instanceof
// console.log(obj instanceof obj2); // error
console.log(obj instanceof Object); //true
console.log(obj instanceof Person); //true
console.log(obj2 instanceof Object); //false
console.log(obj2 instanceof Object); //false
console.log(myObject instanceof Person); //false
console.log(myObject instanceof Object); // true
- person("b",2); 하면 window객체로 값이 들어가서 소스 살펴봤는데 Window객체가 존재하고 window객체가 또 존재
- Window 와 window 의 차이점
- Window는 브라우저에서 최상위 객체를 나타내며,
- window는 브라우저에서 열린 각 창을 나타냅니다.
- 브라우저 창이 여러 개 열리면 각 창은 자체적인 window 객체를 가지고 있고, 이 window 객체는 Window 객체를 상속 받는다.
6.1 call(), apply()로 this의 대상 변경
- call(), apply(), bind()를 사용하면 this()가 가리키는 대상을 변경할 수 있다.
- == 이미 생성된 객체에 적용 가능하다.
function Person(name, age) {
this.name = name;
this.age = age;
}
var p = new Person("tom", 33);
var p3 = {};
var p4 = new Object();
Person.call(p3, "a", 11);
Person.apply(p3, ["b", 0]);
console.log(p3);
6.2. 중첩된 함수에서의 this
- 함수가 중첩되면, this의 의미가 달라진다.
- 방법
- that = this
- bind()
- lambda식()
// 중첩된 함수에서의 this
function Person(name, age) {
console.log(this); // person
temp();
function temp() {
console.log(this); // window
}
}
// that 이용
function Person(name, age) {
console.log(this);
const that = this; // that
temp();
function temp() {
console.log(this); //window
console.log();
console.log(that); // person
}
}
7. 객체의 속성에 접근제한
- 생성자의 변수를 지역변수로 선언하여 접근을 제한
- getter 사용
function Person(name, age) {
// this는 곧 해당 function으로 객체를 만든 참조변수의 주소가 된다.
this.name = name;
this.age = age;
}
var p = new Person("a", 12); // this === p
console.log(p.name);
console.log(p.age);
// undefined 됨
function Person(name, age) {
// this.name = name;
// this.age = age;
var name = name;
var age = age;
}
var p = new Person("a", 12);
console.log(p.name);
console.log(p.age);
// getter로 내부 함수 가져오기
// function이면서 생성자가 될 수있다.
function Person(name, age) {
var name = name;
var age = age;
this.getName = function () {
return name;
};
this.getAge = function () {
return age;
};
}
var p = new Person("a", 12); // new를 통해서 해당 function을 생성자로 사용
console.log(p.getName());
console.log(p.getAge());
8. 두 객체간의 상속관계 맺어주기
- JS 에선 상속관계를 맺는 것은 prototype과 __proto__의 연결을 해주는 과정이다
- super() 역할을 하는 .call() 함수가 존재
// 상속 관계
function Person(name, age) {
this.name = name;
this.age = age;
}
function Manager(dept, name, age) {
Person.call(this, name, age); // super()
this.dept = dept;
}
const m = new Manager("sales", "woo", 12);
// super()를 이용해서 Person 생성자를 호출하지만 아직 상속관계를 맺진 않았다.
console.log(m.age); // 12
console.log(m instanceof Person); // false
// 상속관계 맺기
// manager 함수의 prototype 객체의 __proto__ 부분을 Person 함수의 prototype과 연결 시켜준다.
Manager.prototype.__proto__ = Person.prototype;
console.log(m instanceof Person); // 상속관계를 맺어서 true 반환