var obj = {};
// var obj = new Object() 이다.
// Object 도 기본적으로 함수이다. function Object()
// var o = new obj();
// 이렇게는 사용할 수 없다. obj is not constructor.
// constructor 가 있어야만 new 를 통해서 객체를 만들수 있다.
// 따라서 함수만 new 키워드를 사용 할 수 있다.
var a = {a: 1};
// a ---> Object.prototype ---> null
// Error literal object 에는 prototype 을 재정의 할 수 없음.
//a.prototype.getA = function() {
// return this.a;
//}
// b 의 prototype 이 a 가 된다.
var b = Object.create(a);
// b ---> a ---> Object.prototype ---> null
//console.log(b.a); // 1 (상속됨)
// Error literal object 에는 prototype 을 재정의 할 수 없음.
//b.prototype.getA = function() {
// return "A";
//}
// 일반 객체에는 prototype 을 정의할 수 없다.
// 그냥 prototype 이라는 속성으로 인식함.
try {
var p = {
a: 10,
b: 20
}
// 일반객체에 prototype 을 정의할 수 없음.
// "prototype" 이라는 속성이 추가 되는 것임.
// __proto__ 변수에 매핑 되는 것이 아님.
p.prototype = {
getA: function () {
return this.a;
}
}
console.log("p = ", p);
console.log("p.a = ", p.a);
console.log("p.__proto__ = ", p.__proto__);
console.log("p.prototype = ", p.prototype);
//console.log("p.getA() = ", p.getA()); // p 객체에는 getA 함수가 없음. 프로토타입 체인으로도 찾을 수 없음.
//console.log("p.prototype.getA() = ", p.prototype.getA()); // p.prototype.getA 함수에서 this 지시자를 사용 할 수 없음.
// Object.create(p) 이용하여 p1 이라는 새로운 객체 생성.
// p1.__proto__ = p 이라는 의미가 됨.
console.log();
console.log("=================================================");
console.log("p1 = Object.create(p)");
var p1 = Object.create(p);
console.log("p1 = ", p1);
console.log("p1.__proto__ = ", p1.__proto__);
console.log("p1.prototype = ", p1.prototype); // "prototype" 이라는 속성.
console.log("p1.__proto__.__proto__ = ", p1.__proto__.__proto__);
console.log("p1.a = ", p1.a); // p1.__proto__.a
//console.log("p1.getA() = ", p1.getA()); // p1, p1__proto__ 객체에 getA 라는 함수는 없다.
//console.log("p1.prototype.getA() = ", p1.prototype.getA()); // p1__proto__.prototype.getA 함수에서 this 지시자를 사용 할 수 없음.
} catch(err) {
console.log(err);
}
// prototype 설명 : https://medium.com/@bluesh55/javascript-prototype-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-f8e67c286b67.
// 함수를 정의하는 순간 Prototype Object 도 생성됨.
// Prototype Object 는 일반적인 객체와 같으며 기본적인 속성으로 constructor 와 __proto__ 를 가지고 있음.
// constructor는 Prototype Object와 같이 생성되었던 함수.
// __proto__는 Prototype Link.
// __proto__는 객체가 생성될 때 조상이었던 함수의 Prototype Object를 가리킴.
// Foo 는 function 객체.
// Foo.__proto__ == Function.prototype. 따라서, F.call() 호출 가능하다.
// Foo.constructor 는 Function. Foo.__proto__ 의 생성자.
function Foo() {
this.a = 1;
}
// new 키워드로 객체 생성. 생성자 함수 호출. 생성자를 바탕으로 객체를 생성한다.
// foo.__proto__ 은 Foo.prototype 이다.
// foo.__proto__.constructor 는 function Foo() 이다.
// foo.hasOwnProperty("constructor") === false
var foo = new Foo();
console.log("foo.a", foo.a);
// var foo = new Object();
// foo.__proto__ = Foo.prototype;
// Foo.call(foo);
// prototype과 constructor는 부모자식 관계
if(foo.__proto__ === Foo.prototype) {
console.log("foo.__proto__ === Foo.prototype");
}
if(foo.__proto__.constructor === Foo) {
console.log("foo.__proto__.constructor === Foo");
}
function Person() {
this.name = "anonymous";
this.job = "none";
this.sayHello = function () {
console.log("Hello, my name is " + this.name);
};
}
function Unikys() {
this.name = "Unikys";
this.job = "Programmer";
}
// #1.
Unikys.prototype = new Person();
var unikys1 = new Unikys();
unikys1.sayHello();
//unikys1 instanceof Unikys === true, unikys1 의 prototype 과 Unikys 의 prototype 이 같기 때문.
//unikys1 instanceof Person === true
// unikys1.constructor = function Persion()
// constructor 는 객체에 있는 것이 아니라 prototype 에 있는 것. prototype 의 생성자.(Person객체의 생성자 = function Persion()).
// constructor 가 있는 prototype 을 다른 새로운 객체로 덮어씌우게 되면 원래 자기 자신의 contstructor 는 상실하게 됨.
// 따라서 unikys1 이 new Unikys()로 생성했다고 하더라도 constructor 는 Unikys() 가 아니라 prototype 으로 덮어씌운 객체의 constructor 인 Person() 이 된다.
// #2.
var unikys2 = Object.create(Person.prototype);
unikys2.name = "Unikys";
// 부모 함수의 일부 메서드에 위임을하고 새 개체를 만들지 않으려면 Object.create 를 사용하는 것이 좋음.
// 부모 함수에 있는 속성은 사용할 수 없기 때문에 부모 속성을 사용하지 않는 경우에 사용.
// unikys2.sayHello(); // Error.
// unikys2 의 prototype 을 Person.prototype 으로 정의. unikys2.__proto__ === Person.prototype.
// 대신 Person 의 속성들은 사용할 수 없어서 추가로 정의해야 함.(name 등)
// unikys2 instanceof Person === true
// unikys2.constructor === Person. true.
// #3.
var unikys3 = Object.create(Person);
unikys3.name = "Unikys";
//unikys3.sayHello();
// unikys3 의 prototype 을 Person 으로 정의. unikys3.__proto__ === Person
// unikys3.constructor === Person. false.
// unikys3.constructor === Function. true.
// constructor 는 prototype 의 생성자를 가르킨다.
// unikys3 instanceof Person === false
// unikys3 instanceof Function === true
// Person.isPrototypeOf(unikys3) == true
// prototype은 모든 객체가 공유하고 있어서 한 번만 만들어지지만, this에 넣은 것은 객체 하나를 만들 때마다 메소드도 하나씩 만들어지기 때문에 불필요한 메모리 낭비.
Person.prototype.yell = function () {
console.log("My name is " + this.name);
}
// #4.
// prototype chain 추가.
Unikys.prototype = Object.create(Person.prototype); // Unikys.prototype = Person.prototype; 으로 했을 경우에는 Unikys.prototype 에 속성을 추가하면 Person.prototype 에도 추가가 된다.
// Unikys.prototype.__proto__ === Person.prototype
// Unikys.prototype.constructor === Person
// Unikys.constructor === Function
console.log(Unikys.constructor);
Unikys.prototype.constructor = Unikys;
// Unikys 객체들의 constructor 를 Unikys 로 정의.
var unikys4 = new Unikys();
console.log(unikys4.name);
//unikys4.sayHello();
// unikys4.__proto === Unikys.prototype
// unikys4.constructor === Unikys
// unikys4.hasOwnProperty("constructor") === false
// unikys4.__proto__.hasOwnProperty("constructor") === false
// unikys4.__proto__.hasOwnProperty("yell") === false
// unikys4.__proto__.__proto__.hasOwnProperty("yell") === true
function Vehicle(name, speed) {
this.name = name;
this.speed = speed;
}
Vehicle.prototype.drive = function () {
console.log(this.name + ' runs at ' + this.speed)
};
function Sedan(name, speed, maxSpeed) {
// Vehicle 생성자에 this와 arguments를 적용하라.
// Sedan은 매개변수로 name과 speed, maxSpeed. maxSpeed는 Vehicle이 갖고 있지 않기 때문에 무시. maxSpeed 속성을 따로 추가.
Vehicle.apply(this, arguments)
this.maxSpeed = maxSpeed;
}
// Sedan.prototype = new Vehicle(); // 이렇게 하면 new Sedan 할때 Vehicle 이 두번 호출 되는 결과가 발생한다. 그리고 Vehicle 의 속성까지도 가지게 된다.
Sedan.prototype = Object.create(Vehicle.prototype);
Sedan.prototype.constructor = Sedan;
Sedan.prototype.boost = function () {
console.log(this.name + ' boosts its speed at ' + this.maxSpeed);
};
var sonata = new Sedan('sonata', 100, 200);
sonata.drive(); // 'sonata runs at 100'
sonata.boost(); // 'sonata boosts its speed at 200'
printOwnProperties(sonata);
function printOwnProperties(obj) {
console.log('==============================================');
console.log('============ Print Own Properties ============');
console.log('==============================================');
for (var key in obj) {
console.log('property = ' + key);
console.log('typeof = ' + (typeof key));
console.log('hasOwnProperty = ' + (obj.hasOwnProperty(key)));
console.log('value = ' + obj[key]);
console.log('');
}
}
var c = function() {return a;}
'프로그래밍 > Javascript' 카테고리의 다른 글
undefined ? (0) | 2021.08.06 |
---|---|
javascript containsAll (1) | 2016.11.04 |
[jquery] hide, show 함수, visibility 속성 (0) | 2016.10.28 |
jquery crossdomain ajax jsonp (1) | 2015.10.30 |
한글, 영문 check (0) | 2011.12.27 |