Prototype 객체는 모든 객체의 어머니 같은 존재인듯 하다.
var student = {
name: 'Lee',
score: 90
};
// student에는 hasOwnProperty 메소드가 없지만 아래 구문은 동작한다.
console.log(student.hasOwnProperty('name')); // true
console.dir(student);
다른 언어를 경험해봤으면 체감이 올거같은데 체감이 오지않는다.
다른 언어는 뭔가 hasOwnProperty라는 메소드를 생성 해야만 쓸수있나 보다.
인터널슬롯.. 유저에게 보여지지 않는 은닉화 되어있는 슬롯인듯 하다.
원시적 이면서 인터널슬롯. 당연히 외부에서의 수정을 허락하지 않는 속성을 가지고있다.
__proto__
accessor property로 접근할 수 있다.[[Prototype]] 는 프로토타입 객체를 가리킨다. 감히 직접 접근하지 못한다.
__proto__
라는 접근전용 프로퍼티가 존재한다.
__proto__
프로퍼티에 접근하면 내부적으로 Object.getPrototypeOf가 호출되어 프로토타입 객체를 반환한다.__proto__
프로퍼티로 자신의 부모 객체(프로토타입 객체)인 Object.prototype을 가리키고 있다.var student = {
name: 'Lee',
score: 90
}
console.log(student.__proto__ === Object.prototype); // true
...? 천천히 정리해보면서 나중에 되뇌어 보자..
말장난 같네.. 아직도 혼란스럽다.. 왜둘이 대결하지..
위에서 말해왔던 prototype 객체와 전혀 다른것이다.
뭐가 다를까 궁금하다..!
그렇게 뭐가 다르면 이름좀 다르게 지어주지
function Person(name) {
this.name = name;
}
var foo = new Person('Lee');
console.dir(Person); // prototype 프로퍼티가 있다. 왜? 함수 객체니까!
console.dir(foo); // prototype 프로퍼티가 없다. 왜? 일반 객체니까!
console.log(Person.__proto__ === Function.prototype);
console.log(Person.prototype === foo.__proto__);
관점의 차이.. 유명한 연예인을 볼때 언론에 노출된 연예인 A씨로 볼것인지, 내 친구의 친구의 친구의 친구의 친구. 로 볼것인지 그런 차이인것 같다. 같은 연예인A 씨를 지명하지만 관점은 전혀 다르다..?
같은 프로토타입 객체를 가르키지만, 일반 객체의 입장에서 보는 부모역할 객체로 볼것인지, 함수 객체의 생성자로 사용될 때 함수를 통해 생성될 객체의 부모 역할을 하는 객체로 볼것인지..?
function Person(name) {
this.name = name;
}
var foo = new Person('Lee');
// Person() 생성자 함수에 의해 생성된 객체를 생성한 객체는 Person() 생성자 함수이다.
console.log(Person.prototype.constructor === Person);
// foo 객체를 생성한 객체는 Person() 생성자 함수이다.
console.log(foo.constructor === Person);
// Person() 생성자 함수를 생성한 객체는 Function() 생성자 함수이다.
console.log(Person.constructor === Function);
var student = {
name: 'Lee',
score: 90
}
// Object.prototype.hasOwnProperty()
console.log(student.hasOwnProperty('name')); // true
console.log(student.__proto__ === Object.prototype); // true
console.log(Object.prototype.hasOwnProperty('hasOwnProperty')); // true
객체의 생성 방법은 3가지다
객체 리터럴
생성자 함수
Object() 생성자 함수
객체 리터럴 방식으로 생성된 객체는 결국 내장 함수(Built-in)인 Object() 생성자 함수로 객체를 생성하는 것을 단순화시킨 것이다.
자바스크립트 엔진은 객체 리터럴로 객체를 생성하는 코드를 만나면 내부적으로 Object() 생성자 함수를 사용하여 객체를 생성한다.
Object() 생성자 함수는 물론 함수이다. 따라서 함수 객체인 Object() 생성자 함수는 일반 객체와 달리 prototype 프로퍼티가 있다.
prototype 프로퍼티는 함수 객체가 생성자로 사용될 때 이 함수를 통해 생성된 객체의 부모 역할을 하는 객체, 즉 프로토타입 객체를 가리킨다.
[[Prototype]]은 객체의 입장에서 자신의 부모 역할을 하는 객체, 즉 프로토타입 객체를 가리킨다.
이제 이해보단 세뇌당하는것 같다.
var person = {
name: 'Lee',
gender: 'male',
sayHello: function(){
console.log('Hi! my name is ' + this.name);
}
};
console.dir(person);
console.log(person.__proto__ === Object.prototype); // ① true
console.log(Object.prototype.constructor === Object); // ② true
console.log(Object.__proto__ === Function.prototype); // ③ true
console.log(Function.prototype.__proto__ === Object.prototype); // ④ true
생성자 함수로 객체를 생성하기 위해서는 우선 생성자 함수를 정의하여야 한다.
함수를 정의하는 방식은 3가지가 있다.
함수 선언신
함수 표현식
Function() 생성자 함수
함수선언식, 함수표현식 모두 함수 리터럴 방식을 사용한다. 함수 리터럴 방식은 Function() 생성자 함수로 함수를 생성하는 것을 단순화 시킨 것이다.
3가지 함수 정의 방식은 결국 Function() 생성자 함수를 통해 함수 객체를 생성한다.
따라서 어떠한 방식으로 함수 객체를 생성하여도 모든 함수 객체의 prototype 객체는 Function.prototype이다
따라서 어떠한 방식으로 함수 객체를 생성하여도 모든 함수 객체의 prototype 객체는 Function.prototype이다
function Person(name, gender) {
this.name = name;
this.gender = gender;
this.sayHello = function(){
console.log('Hi! my name is ' + this.name);
};
}
var foo = new Person('Lee', 'male');
console.dir(Person);
console.dir(foo);
console.log(foo.__proto__ === Person.prototype); // ① true
console.log(Person.prototype.__proto__ === Object.prototype); // ② true
console.log(Person.prototype.constructor === Person); // ③ true
console.log(Person.__proto__ === Function.prototype); // ④ true
console.log(Function.prototype.__proto__ === Object.prototype); // ⑤ true
function Person(name) {
this.name = name;
}
var foo = new Person('Lee');
Person.prototype.sayHello = function(){
console.log('Hi! my name is ' + this.name);
};
foo.sayHello();
var str = 'test';
console.log(typeof str); // string
console.log(str.constructor === String); // true
console.dir(str); // test
var strObj = new String('test');
console.log(typeof strObj); // object
console.log(strObj.constructor === String); // true
console.dir(strObj);
// {0: "t", 1: "e", 2: "s", 3: "t", length: 4, __proto__: String, [[PrimitiveValue]]: "test" }
console.log(str.toUpperCase()); // TEST
console.log(strObj.toUpperCase()); // TEST
var str = 'test';
// 에러가 발생하지 않는다.
str.myMethod = function () {
console.log('str.myMethod');
};
str.myMethod(); // Uncaught TypeError: str.myMethod is not a function
var str = 'test';
String.prototype.myMethod = function () {
return 'myMethod';
};
console.log(str.myMethod()); // myMethod
console.log('string'.myMethod()); // myMethod
console.dir(String.prototype);
프로토타입 체인으로 myMethod를 찾아가는것 같다.
var str = 'test';
String.prototype.myMethod = function() {
return 'myMethod';
}
console.log(str.myMethod());
console.dir(String.prototype);
console.log(str.__proto__ === String.prototype); // ① true
console.log(String.prototype.__proto__ === Object.prototype); // ② true
console.log(String.prototype.constructor === String); // ③ true
console.log(String.__proto__ === Function.prototype); // ④ true
console.log(Function.prototype.__proto__ === Object.prototype); // ⑤ true
점점 프로토타입에 스며드는 느낌이다. 이해가 된다보다는 원래 이런것이구나 라는느낌으로 습득중
function Person(name) {
this.name = name;
}
var foo = new Person('Lee');
// 프로토타입 객체의 변경
Person.prototype = { gender: 'male' };
var bar = new Person('Kim');
console.log(foo.gender); // undefined
console.log(bar.gender); // 'male'
console.log(foo.constructor); // ① Person(name)
console.log(bar.constructor); // ② Object()
function Person(name) {
this.name = name;
}
Person.prototype.gender = 'male'; // ①
var foo = new Person('Lee');
var bar = new Person('Kim');
console.log(foo.gender); // ① 'male'
console.log(bar.gender); // ① 'male'
// 1. foo 객체에 gender 프로퍼티가 없으면 프로퍼티 동적 추가
// 2. foo 객체에 gender 프로퍼티가 있으면 해당 프로퍼티에 값 할당
foo.gender = 'female'; // ②
console.log(foo.gender); // ② 'female'
console.log(bar.gender); // ① 'male'
객체에 할당 할때는 우선적으로 재할당 하거나 동적추가 하기때문에 프로토타입 체인은 동작하지 않는다.