객체 = 언어 차원에서 제공되는 문법적인 기능
하나의 객체 안에는 그 객체가 가지고 있는 취지, 혹은 기능과 연관되어있는 변수와 메소드가 담겨 있고 서로 연관성이 없는 다른 로직과 구분해주는 역할을 함.
또한, 이미 사용하고 있는 로직을 다른 곳에 사용하는 '재활용성'에도 기여함.
즉, 객체는 변수와 메소드를 grouping한 것.
(재활용이 가능하도록) 부품화
은닉화/캡슐화 = 내부의 동작 방법을 단단한 케이스(객체) 안으로 숨기고, 사용자에게는 그 부품(메소드)의 사용방법만을 노출하는 것.
즉, 객체가 어떻게 만들어졌는지 몰라도 객체를 사용할 수 있도록 하는 것.
인터페이스 = 부품들 간의 약속. 이질적인 것들이 결합하는 것을 막아주는 역할도 함.
자바스크립트 > Prototype-based programming
var person = {}
person.name = 'egoing';
person.introduce = function(){
return 'My name is' + this.name;
}
document.write(person.introduce());
name, introduce : 변수/프로퍼티(property)/속성
function() : 메소드(method)
객체를 정의할 때 값을 세팅하도록 코드를 변경하면,
var person = {
'name' : 'egoing',
'introduce' : function(){
return 'My name is '+this.name;
}
}
document.write(person.introduce());
생성자(constructor) = 객체를 만드는 역할을 하는 함수
함수를 호출할 때 new를 붙이면 새로운 객체를 만든 후에 이를 리턴한다.
function Person(){}
var p0 = Person();
p0 // undefined
function Person(){}
var p = new Person();
p // Person{}
function Person(name){
this.name = name;
this.introduce = function(){
return 'My name is '+this.name;
}
}
var p1 = new Person('egoing');
document.write(p1.introduce()+"<br />");
var p2 = new Person('leezche');
document.write(p2.introduce());
자바스크립트에서 모든 객체는 기본적으로 전역객체의 프로퍼티
function func(){
alert('Hello?');
}
func(); // Hello?
window.func(); // Hello?
모든 전역변수와 함수는 사실 window 객체의 프로퍼티다. 객체를 명시하지 않으면 암시적으로 window의 프로퍼티로 간주된다.
호스트환경에 따라 전역객체의 이름/전역객체의 메소드 존재 유무가 달라진다.
이를테면 웹브라우저 자바스크립트에서는 alert()이라는 전역객체의 메소드가 존재하지만 node.js에는 존재하지 않는다. 또한 전역객체의 이름도 호스트환경에 따라서 다른데, 웹브라우저에서 전역객체는 window이지만 node.js에서는 global이다.
⭐️ this : 함수를 어떻게 호출하느냐에 따라서 this가 가리키는 대상이 달라진다
function func(){
if(window === this){
document.write("window === this");
}
}
func();
// window === this
var o = {
func : function(){
if(o === this){
document.write("o === this");
}
}
}
o.func();
// o === this
var funcThis = null;
function Func(){
funcThis = this;
}
var o1 = Func();
if(funcThis === window){
document.write('window <br />');
}
var o2 = new Func();
if(funcThis === o2){
document.write('o2 <br />');
}
// window, o2
function sum(x,y){return x+y;} >> 함수 리터럴
=
var sum = new Function('x', 'y', 'return x+y;'};
var o = {}
var p = {}
function func(){
switch(this){
case o:
document.write('o<br />');
break;
case p:
document.write('p<br />');
break;
case window:
document.write('window<br />');
break;
}
}
func(); // window
func.apply(o); // o
func.apply(p); // p
객체는 연관된 로직들로 이루어진 작은 프로그램이라고 할 수 있다. 상속은 객체의 로직을 그대로 물려 받는 또 다른 객체를 만들 수 있는 기능을 의미한다. 단순히 물려받는 것이라면 의미가 없을 것이다. 기존의 로직을 수정하고 변경해서 파생된 새로운 객체를 만들 수 있게 해준다.
function Person(name){
this.name = name;
}
Person.prototype.name=null;
Person.prototype.introduce = function(){
return 'My name is '+this.name;
}
function Programmer(name){
this.name = name;
}
Programmer.prototype = new Person();
var p1 = new Programmer('egoing');
document.write(p1.introduce()+"<br />");
Programmer이라는 생성자를 만들었다. 그리고 이 생성자의 prototype과 Person의 객체를 연결했더니 Programmer 객체도 메소드 introduce를 사용할 수 있게 되었다.
Programmer가 Person의 기능을 상속하고 있는 것이다. 단순히 똑같은 기능을 갖게 되는 것이라면 상속의 의의는 사라질 것이다. 부모의 기능을 계승 발전할 수 있는 것이 상속의 가치다.
function Person(name){
this.name = name;
}
Person.prototype.name=null;
Person.prototype.introduce = function(){
return 'My name is '+this.name;
}
function Programmer(name){
this.name = name;
}
Programmer.prototype = new Person();
Programmer.prototype.coding = function(){
return "hello world";
}
var p1 = new Programmer('egoing');
document.write(p1.introduce()+"<br />");
document.write(p1.coding()+"<br />");
// My name is egoing
hello world
객체는 프로퍼티를 가질 수 있는데 prototype이라는 프로퍼티는 그 용도가 약속되어 있는 특수한 프로퍼티다. prototype에 저장된 속성들은 생성자를 통해서 객체가 만들어질 때 그 객체에 연결된다.
prototype chain = 객체와 객체를 연결하는 체인 역할
function Ultra(){}
Ultra.prototype.ultraProp = true;
function Super(){}
Super.prototype = new Ultra();
function Sub(){}
Sub.prototype = new Super();
var o = new Sub();
console.log(o.ultraProp);
//true
내장 객체 = 자바스크립트가 기본적으로 가지고 있는 객체
(ex. Object/Function/Array/String/Boolean/Numer/Math/Date/RegExp)
<-> 사용자 정의 객체
object 객체는 객체의 가장 기본적인 형태를 가지고 있는 객체. 즉, 아무것도 상속받지 않는 순수한 객체
Object 객체는 확장하지 않는 것이 바람직하다. 왜냐하면 모든 객체에 영향을 주기 때문이다.
Object.prototype.hasOwnProperty() = 인자로 전달된 어떠한 값이 객체의 속성인지 여부를 판단
원시(기본) 데이터 타입 vs. 객체(참조) 데이터 타입
문자열과 같은 원시 데이터 타입은 객체로서 사용할 때 임시로 객체로 만들어준다.
ex. 숫자 > number, 문자열 > string, true/false > Boolean, null > X, undefined > X)
[변수에 담긴 값이 원시 데이터 타입일 경우]
var a = 1; var b = a; b = 2; console.log(a); // 1
[변수에 담긴 값이 객체(참조 데이터 타입)일 경우]
var a = {'id':1}; var b = a; b.id = 2; console.log(a.id); // 2
var a = {'id':1};
function func(b){
b = {'id':2};
}
func(a);
console.log(a.id); // 1
var a = {'id':1};
function func(b){
b.id = 2;
}
func(a);
console.log(a.id); // 2