Value vs Reference, Order of Execution, Prototype chaining
<Value vs Reference: 참조 타입과 원시 타입 복사 정리>
- 데이터 타입에는 참조 타입(reference type)과 원시 타입(primitive type)이 있다.
- 변수 간에 원시 타입 데이터를 복사하면 데이터 값이 복사된다.
var x = 2;
var y = x; // x는 원시타입 데이터이므로, y에 x값을 그대로 카피해 넣는다.
y = 3;
console.log(x) // x는 y의 영향을 받지 않으므로, 2
- 반면 변수 간에 참조 타입 데이터를 복사하면 주소가 넘어간다. 참조 타입 복사와 관련하여 사례 몇 가지를 정리해 보았다.
// case 1
var x = { foo: 3 };
var y = x; // x는 참조 타입이므로, { foo: 3 }이라는 객체의 주소가 y에 할당된다.
y.foo = 3;
console.log(x.foo) // 3
// case 2
var x = { foo: 3 };
var y = x; // y도 x처럼, { foo: 3 }이라는 객체의 주소를 바라보게 되었다.
y = 2; // y 변수에 원시타입 데이터 2가 할당되었을 뿐,
console.log(x.foo) // x에는 영향을 주지 않았으므로 x.foo는 여전히 3이다.
// case 3
var myArray = [2, 3, 4, 5];
function doStuff(arr) {
arr = [];
}
doStuff(myArray); // myArray가 아니라, doStuff라는 함수 안의 변수 arr이 []을 가리키게 된 것.
myArray // [2,3,4,5]
<Order of Execution>
- 함수 실행과 관련하여 헷갈리는 사례 몇 가지를 정리해 보았다.
// case 1
var x = 10;
function func(){
x = x + 1;
return x;
}
var result = [x, func(), x];
console.log(result) // 여기서 result는? [10, 11, 11]
// result[0]은 전역의 x를 바라보므로 10
// result[1]의 func()는 11, 즉 func 함수의 리턴값. 전역변수 x에 담긴 10에 1을 더했다.
// result[2]는 11.
// 순서대로 값을 넣는다는 것이 포인트!!
// case 2
var x = 10;
function f (){
x = x + 1;
return x;
}
var obj = { // 각 프로퍼티는 인스턴스가 생성될 때 그 값이 결정된다.
func: f, // func는 f라는 함수의 주소를 참조하고 있다.
g: f(), // f라는 함수가 실행된 후 리턴한 값. 즉 11.
h: x // g 프로퍼티가 생성될 때 x는 이미 11이 되어 있었으므로, h 또한 11.
};
obj.func()
var result = obj.g
console.log(result) // 여기서 result는? 11
// case 3
var x = 10;
var obj = { // 인스턴스 자체가 생성될 때 각 프로퍼티의 값이 할당되었다.
y: x, // 글로벌의 x값이 그대로 복사됨. 10.
z: obj.y + 1 // z에 값이 할당될 당시 obj는 undefined이다.
};
var result = obj.z
console.log(result) // obj.y를 읽을 수 없다는 오류가 나온다.
<Prototype chaining 관련 개념>
- 상속(inheritance)이란 상위 객체의 특징을 하위 객체에게 넘겨주는 것이다. 자식 객체는 부모 객체의 기능을 물려받으면서도, 동시에 또 다른 기능을 가질 수 있다.
- 서브클래싱(subclassing)이란 부모 클래스(super class)와 유사한 자식 클래스(sub class)를 생성하여 코드를 공유하는 패턴이다. 자식 클래스들은 부모 클래스로부터 속성을 상속받는 동시에, 또 다른 자식 클래스들을 재정의 할 수도 있다.
- Prototype: 함수 객체만 가지고 있는 프로퍼티다. 함수 객체가 생성자로 사용될 때, 이 함수를 통해 생성될 인스턴스의 부모 역할을 하는 객체를 가리킨다.
- __proto__: 인스턴스 입장에서 자신의 부모 역할을 하는 객체, 즉 프로토타입 객체를 가리킨다.
→ prototype 프로퍼티와, __proto__는 비슷하지만 다르다. 둘 다 프로토타입 객체를 가리키지만 관점의 차이가 있다.
- constructor: 프로토타입 객체가 갖는 프로퍼티. 특정 객체가 생성될 때 실행된다.
- prototype chaining: 특정 객체의 프로퍼티나 메소드에 접근하려고 할 때, 해당 객체에 접근하려는 프로퍼티나 메소드가 없다면 __Prototype__이 가리키는 링크를 따라 자신의 부모 역할을 하는 프로토타입 객체의 프로퍼티나 메소드를 차례대로 검색한다.