prototype pollution을 공부하기 위해 JavaScript의 객체와 프로토 타입이 무엇인지 먼저 알아보도록 한다.
참조: https://developer.mozilla.org/ko/docs/Learn/JavaScript/Objects/Basics
JavaScript 객체
객체는 관련된 데이터와 함수( 객체 안에 있을 때는 프로퍼티와 메소드라 호칭)의 집합이다. 객체를 생성해 볼 것인데, 다른 요소들과 마찬가지로 변수를 정의하고, 초기화하는 것으로 시작한다.
<script> var person = {}; </script>
[object Object]
Object { }
{ }
person 객체는 빈 객체임을 console창에서 확인할 수 있다. 아래와 같이 객체를 업데이트 해본다.
const person = {
name: ["Bob", "Smith"],
age: 32,
gender: "male",
interests: ["music", "skiing"],
bio: function () {
alert(
this.name[0] +
" " +
this.name[1] +
" is " +
(중략...)
);
},
greeting: function () {
alert("Hi! I'm " + this.name[0] + ".");
},
};
person.name;
person.name[0];
person.greeting();
위 person 객체는 각기 다른 이름( name, age.. )과 값( ['Bob','Smith'], 32 )을 갖는 복수 개의 멤버로 구성된다. 즉 아래와 같은 문법 패턴을 가진다.
var objectName = {
member1Name: member1Value,
member2Name: member2Value,
};
객체를 구성하는 멤버의 값은 어떤 것이라도 될 수 있다. 위에서 만든 person 객체는 문자열, 숫자, 배열 두개와 두 개의 함수를 가진다. 처음 4개의 아이템은 데이터 아이템인데, 이것을 객체의 프로퍼티(속성)이라 부른다. 끝에 두 개의 아이템은 함수인데 이것을 메소드라고 부른다.
해당 person과 같은 객체는 객체를 생성할 때 컨텐츠를 그대로 대입했으므로 객체 리터럴(object literal)이라 부른다. ( 객체 리터럴은 클래스로 부터 생성하는 방식과 다름 )
또한, 객체 이름(person)은 네임스페이스처럼 동작한다. 객체 내에 캡슐화되어 있는 것에 접근하려면 먼저 점을 입력해야 한다. ( ex. person.bio(); )
하위 namespaces를 만들 수도 있는데, 그 예는 아래와 같다.
name: ['Bob', 'Smith'],
name : {
first: 'Bob',
last: 'Smith'
},
이와 같이 하위 namespace를 만들었다. 이 속성을 사용하기 위해서는 아래와 같이 끝에 다른 점을 하나 찍어주기만 하면 된다.
person.name.first;
person.name.last;
person.name[0] 와 같이 접근 x
객체의 속성이 바뀌었으니, 기존 메소드(bio, greeting) 코드 또한 변경해줘야 한다. 만약 변경하지 않으면, Hi! I'm undefined. 이와 같은 메시지를 얻을 수 있다. 그러므로 아래와 같이 코드를 변경해 준다.
name[0] -> name.first;
name[1] -> name.last;
지금까지는 점 표기 법을 위주로 살펴봤었다. 이제 괄호 표기법에 대해 알아보도록 한다.
person.age; ---> person["age"];
person.name.first; ---> person["name"]["first"];
괄호 표기법은 배열 속에 있는 항목에 접근하는 방법과 매우 유사해보이는데, 기본적으로도 동일한 것이다. 한 항목을 선택하기 위해 인덱스 숫자를 이용하는 대신에 각 멤버의 값들과 연결된 이름을 이용한다. 객체가 간혹 연관 배열 (associative arrays)라고 불리는 것이 당연하다. 연관 배열은 배열이 숫자를 값에 연결하는 것과 같은 방법으로 문자열을 값에 매핑한다.
지금부터는 객체 멤버를 단순히 가져오기만(반환) 하는 것이 아닌, 설정할 멤버를 명시하여 객체 멤버의 값을 설정(갱신) 하는 것을 살펴보도록 한다.
person.age = 45;
person["name"]["last"] = "Cratchit";
또한 객체 멤버를 설정하는 것은 단순히 기존에 존재하는 프로퍼티나 메소드로 값을 설정하는 것뿐 아니라, 완전히 새로운 멤버를 생성할 수도 있다.
person["eyes"] = "hazel";
person.farewell = function () {
alert("Bye everybody!");
};
person["eyes"];
person.farewell();
이번에는 this란 무엇인가 알아보도록 한다.
greeting: function() {
alert('Hi! I\'m ' + this.name.first + '.');
}
this 키워드는 지금 동작하고 있는 코드를 가지고 잇는 객체를 가리킨다. 위의 예제에서 this는 person 객체와 동일한 것이다.