
< 객체 선언시 사용 방법 >
1. object 생성해 객체 생성
2. class를 인스턴화해서 생성
3. function 사용해 객체 생성
const yujin = {
name: '안유진',
year: 2003,
};
console.log(yujin);
// result > { name: '안유진', year: 2003 }
class Idole {
name;
year;
constructor(name, year) {
this.name = name;
this.year = year;
}
};
const yujin2 = new Idole('안유진', 2003);
console.log(yujin2);
// result > Idole { name: '안유진', year: 2003 }
function IdoleFunction(name, year) {
this.name = name;
this.year = year;
}
const liz = new IdoleFunction('리즈', 2004);
console.log(liz);
// result > IdoleFunction { name: '리즈', year: 2004 }
const yujin = {
name: '안유진',
year: 2003,
};
// 생성자 함수 혹은 클래스에 바로 .이 붙으면 static
console.log(Object.getOwnPropertyDescriptor(yujin, 'name'));
console.log(Object.getOwnPropertyDescriptor(yujin, 'year'));
// 모든 프로퍼티의 값 보여줌
console.log(Object.getOwnPropertyDescriptors(yujin));
키와 값으로 형성된 실질적 값을 갖고 있는 프로퍼티
- 다음 값을 따로 설정하지 않으면, 기본값은 false
- value - 실제 프로퍼티의 값
- writeable - 값 수정 여부. false이면 프로퍼티 값 수정 불가
- enmerable - 열거 가능 여부. for ... in 등 사용가능시 true
- configurable - 프로퍼티 어트리뷰트 재정의 가능 여부 판단
- false 일 경우 프로퍼티 삭제 혹은 어트리뷰트 변경 금지
- writeable 이 true 인 경우 값 변경 및 writzble 변경 가능
const yujin2 = {
name: '안유진',
year: 2003,
get age() {
return new Date().getFullYear() - this.year
},
set age(age) {
this.year = new Date().getFullYear() - age;
}
};
console.log(yujin2);
console.log(yujin2.age);
yujin2.age = 32;
console.log(yujin2.age);
console.log(yujin2.year);
console.log(Object.getOwnPropertyDescriptor(yujin2, 'age'))
false 이면 프로퍼티 값 수정 불가Object.defineProperty(yujin2, 'height', {
value: 172,
// 아래 모두 설정 하지 않으면, 기본값은 false
writable: true,
enumerable: true,
configurable: true,
});
console.log(yujin2);
console.log(Object.getOwnPropertyDescriptor(yujin2, 'height'));
yujin2.height = 168;
console.log(yujin2);
Object.defineProperty(yujin2, 'height', {
value: 172,
writable: false,
});
console.log(Object.getOwnPropertyDescriptor(yujin2, 'height'));
yujin2.height = 180;
console.log(yujin2); // 오류는 나지 않지만 값 변경X
for ... in 등 사용 가능시 trueconsole.log(Object.keys(yujin2));
for (let key in yujin2) {
console.log(key);
}
name 프로퍼티 enumerable : falseObject.defineProperty(yujin2, 'name', {
enumerable: false,
});
console.log(Object.getOwnPropertyDescriptor(yujin2, 'name'));
console.log(Object.keys(yujin2));
for (let key in yujin2) {
console.log(key);
};
console.log(yujin2);
console.log(yujin2.name);
false => 프로퍼티 삭제 및 어트리뷰트 변경 금지writable : true => 값 변경 및 writable 변경 가능Object.defineProperty(yujin2, 'height', {
writable: true,
configurable: false,
});
console.log(Object.getOwnPropertyDescriptor(yujin2, 'height'));
writable: true => configurable : false 여도 값 변경 가능Object.defineProperty(yujin2, 'height', {
value: 168,
})
console.log(Object.getOwnPropertyDescriptor(yujin2, 'height'));
writable: false 변경Object.defineProperty(yujin2, 'height', {
writable: false
})
console.log(Object.getOwnPropertyDescriptor(yujin2, 'height'));
writable: false -> writable: true 변경 => Error 발생Object.defineProperty(yujin2, 'height', {
writable: true,
})
console.log(Object.getOwnPropertyDescriptor(yujin2, 'height'));
자체적으로 값을 갖고 있지 않지만 다른 값을 가져오거나 설정할 때 호출되는 함수로 구성된 프로퍼티
(ex. getter/setter)
- Extensible : 확장 가능 여부 설정
- Seal
- Freezed : 동결 => 읽기 외 모든 기능 불가능하게 만듦
const yujin = {
name: '안유진',
year: 2003,
get age() {
return new Date().getFullYear - this.year;
},
set age(age) {
this.age = new Date().getFullYear - age;
}
};
console.log(yujin);
extensible 확인console.log(Object.isExtensible(yujin));
yujin['position'] = 'vocal';
console.log(yujin);
extensible : false 변경Object.preventExtensions(yujin);
console.log(Object.isExtensible(yujin));
extensible : false => 에러창NO, 값 추가Xyujin['group'] = '아이브';
console.log(yujin);
delete yujin['position'];
console.log(yujin);
const yujin2 = {
name: '안유진',
year: 2003,
get age() {
return new Date().getFullYear - this.year;
},
set age(age) {
this.age = new Date().getFullYear - age;
}
};
console.log(yujin2);
seal 확인console.log(Object.isSealed(yujin2));
Seal : true 변경Object.seal(yujin2);
console.log(Object.isSealed(yujin2));
Seal : true => 값 추가Xyujin2['group'] = '아이브';
console.log(yujin2);
Seal : true => 값 삭제Xdelete yujin2['name'];
console.log(yujin2)
configurable : false 작업Object.defineProperty(yujin2, 'name', {
value: '가나다',
writable: false
})
console.log(Object.getOwnPropertyDescriptor(yujin2, 'name'));
const yujin3 = {
name: '안유진',
year: 2003,
get age() {
return new Date().getFullYear - this.year;
},
set age(age) {
this.age = new Date().getFullYear - age;
}
};
console.log(yujin3);
console.log(Object.isFrozen(yujin3));
Object.freeze(yujin3);
console.log(Object.isFrozen(yujin3));
yujin3['group'] = '아이브';
console.log(yujin3);
delete yujin3['name'];
console.log(yujin3);
Object.defineProperties(yujin3, 'name', {
CSSMathValue : '가나다'
})
const yujin4 = {
name: '안유진',
year: 2003,
liz: {
name: '리즈',
year: 2004
}
};
Object.freeze(yujin4);
console.log(Object.isFrozen(yujin4));
console.log(Object.isFrozen(yujin4['liz']));
function Idol(name, year) {
this.name = name;
this.year = year;
this.dace = function () {
return `${this.name}이 춤을 춘다.`
}
}
const yujin = new Idol('안유진', 2003);
console.log(yujin);
console.log(yujin.dace());
new 키워드 없이 함수형 실행시undefinedconst yujin2 = Idol('안유진', 2003);
console.log(yujin2);
💡 함수를 다음과 같이 바꾸면
=> if 문에서 undefined 인 경우,new키워드를 이용해 강제로 Idol 함수를 생성자 함수로 실행
function Idol(name, year) {
//new 키워드 여부 없이 아래 객체 생성가능
if (!new.target) {
return new Idol(name, year)
}
this.name = name;
this.year = year;
this.dace = function () {
return `${this.name}이 춤을 춘다.`
}
}
new 키워드 사용 없이 사용자 함수 실행시this 키워드가 global 에 붙어global 의 값을 설정하게 됨console.log(global.name);
const IdolArrow = (name, year) => {
this.name = name;
this.year = year;
};
new 키워드는 일반 함수에서만 사용 가능Arrow 함수 사용 불가const yujin3 = new IdolArrow('안유진', 2003);
__proto__
: 모든 객체에 존재하는 프로퍼티
: 상속에서 부모 클래스에 해당되는 값
: 유전자라고 생각하면 쉬움ㅎ
const testObj = {};
console.log(testObj.__proto__);
function Idol(name, year) {
this.name = name;
this.year = year;
}
console.log(Idol.prototype);
console.dir(Idol.prototype, {
showHidden: true,
});
console.log(Idol.prototype.constructor === Idol);
console.log(Idol.prototype.constructor.prototype === Idol.prototype);
const yujin = new Idol('안유진', 2003);
console.log(yujin.__proto__);
console.log(yujin.__proto__ === Idol.prototype);
console.log(testObj.__proto__ === Object.prototype);
console.log(Idol.__proto__ === Function.prototype);
console.log(Function.prototype.__proto__ === Object.prototype);
console.log(Idol.prototype.__proto__ === Object.prototype);
console.log(yujin.toString());
console.log(Object.prototype.toString());
💡 어떤 부분이 유용?
function Idol2(name, year) {
this.name = name;
this.year = year;
this.sayHi = function () {
return `${this.name}이 인사를 합니다.`
}
}
const liz = new Idol2('리즈', 2004);
const ray = new Idol2('레이', 2004);
console.log(liz.sayHi());
console.log(ray.sayHi());
false ?console.log(liz.sayHi === ray.sayHi);
console.log(liz.hasOwnProperty('sayHi'));
// > result > true
function Idol3(name, year) {
this.name = name;
this.year = year;
};
Idol3.prototype.sayHello = function () {
return `${this.name} 이(가) 인사를 합니다.`
}
const liz2 = new Idol3('리즈', 2004);
const ray2 = new Idol3('레이', 2004);
console.log(liz2.sayHello());
console.log(ray2.sayHello());
true ?console.log(liz2.sayHello === ray2.sayHello);
false => 상속받은 프로퍼티console.log(liz2.hasOwnProperty('sayHello'));
Idol3.sayStaticHello = function () {
return 'Hi! I am static method'
};
console.log(Idol3.sayStaticHello());
function Idol4(name, year) {
this.name = name;
this.year = year;
// 오버라이딩
this.sayHello = function () {
return 'Hi! instnace method'
}
};
Idol4.prototype.sayHello = function () {
return `Hi! prototype method!`
}
const liz3 = new Idol4('리즈', 2004);
console.log(liz3.sayHello());
function IdolModel(name, year) {
this.name = name;
this.year = year;
}
IdolModel.prototype.sayHello = function () {
return `${this.name} Hello!`
}
function FemaleIdol(name, year) {
this.name = name;
this.year = year;
this.dance = function () {
return `${this.name} is dancing!`
}
}
const gaEil = new IdolModel('가을', 2002);
const WY = new FemaleIdol('장원영', 2004);
console.log(gaEil.__proto__);
console.log(gaEil.__proto__ === IdolModel.prototype);
console.log(Object.getPrototypeOf(gaEil) === IdolModel.prototype);
console.log(gaEil.sayHello());
console.log(WY.dance());
FemaleIdol의 객체로 IdolModel의 프로토인 sayHello 함수 사용 불가console.log(WY.sayHello());
💡 프로토 변경
: 기존 프로토와 연결 끊김
=> 기존 프로토가 변경할 프로토와 연결되는 것은 아님
Object.setPrototypeOf(WY, IdolModel.prototype);
console.log(WY.sayHello());
console.log(WY.constructor);
console.log(WY.constructor === FemaleIdol);
console.log(WY.constructor === IdolModel);
FemaleIdol.prototype = IdolModel.prototype;
const ive = new FemaleIdol('아이브', 2022);
console.log(Object.getPrototypeOf(ive) === FemaleIdol.prototype);
console.log(FemaleIdol.prototype === IdolModel.prototype);
이렇게 유용한 정보를 공유해주셔서 감사합니다.