JavaScript Object 생성

JavaScript Object 생성

* blogger에 highlight.js를 적용한 기념으로~~~~~~ ^^

일반적으로

var Person = function () {
};

내부 프로퍼티 추가

var Person = function () {
    this.firstname = 'First Name'; // property 추가
};

이부분에서 생성 방식을 Object와 비교
var obj = new Object();
console.log(obj.contructor === Object); // true

// 생성 형태가 Number로
var obj = new Object(1);
console.log(obj.contructor === Number); // true

// 생성 형태가 String으로
var obj = new Object('1');
console.log(obj.contructor == String); // true

// 생성 형태가 Boolean으로
var obj = new Object(true);
console.log(obj.contructor == Boolean); // true



이와 같이 하면, Person 생성자 함수(일명 class)를 만든 것이다. 그런데 문제가, "fullname()"함수는 hoisting 된 함수를 사용하기 때문에, 전역에 걸쳐 있는 함수를 참조하게 되고, 또한, 변수에 대한 전달이 되지도 않는다.



이와 같이 하면, 약간 더 세련되어졌지만, 여전히 문제를 가지고 있다. "fullname()"함수가 Person 객체를 생성할 때마다 복제되어 생성된다는 것이다. 즉 "new Person()"를 10번 하면 "fullname()"함수도 10번 생성된다는 뜻이다.



이와 같이 하면, 나름대로 좋은 형태로 구성했다고 해도 된다.
밑부분에 적은 것처럼 다른 this를 실제로 반환해도 된다.

var Person = function () {
    //var this = Object.create(Person.prototype); <= 내부에서 발생되는 행동 예시
    this.firstname = firstname;
    this.lastname = lastname;
    //return this; <= 내부에서 발생되는 행동 예시
    // 필요한 경우 다른 this를 생성해서 반환할수도 있다.
    var that = Object.create(Person.prototype);
    //var that = {}; <= 이렇게 하면 prototype을 사용할 수 없다.
    that.name = 'I have no name!';
    return that;
};

Person.prototype.fullname = function () {
    //return this.firstname + '!, ' + this.lastname + ' ' + this.firstname + '!'; // exception!
    return this.name;
};

이처럼 해버리면, 이전에 선언한 "firstname"와 "lastname"은 모두 무시되어 버린다.
신중하자.

그럼 new 없이 사용하면? prototype chain이 끊기게 된다.
var person1 = new Person('James', 'Bond');
console.log(typeof person1); // 'object'
console.log(person1.fullname()); // 'My Name is Bond! James Bond!'
var person2 = Person('James', 'Bond');
console.log(typeof person2); // 'undefined' <= 주목하자!
console.log(person2.fullname()); // My Name is Bond! James Bond!'

개별적인 생성자를 강제하려면, 즉, new 를 사용하지 않아도 new로 생성해서 반환하도록 해주면 된다.
var Person = function (firstname, lastname) {
    if (!(this instanceof arguments.callee)) {
        return new arguments.callee(firstname, lastname); // 이와 같은 방식으로 호출 가능
    }
    this.firstname = firstname;
    this.lastname = lastname;
};
// arguments.callee 배제 (ES5 이후 deprecated)
var Person = function Person(firstname, lastname) {
    if (!(this instanceof Person)) {
        return new Person(firstname, lastname);
    }
    this.firstname = firstname;
    this.lastname = lastname;
};

Person.prototype.fullname = function () {
    return this.firstname + '!, ' + this.lastname + ' ' + this.firstname + '!';
};

var person1 = new Person('James', 'Bond');
var person2 = Person('James', 'Bond');

댓글

이 블로그의 인기 게시물

Next.js에서 자연스러운 Page Transition 방법

[flutter] Android - Package간 sdk version 등이 맞지 않아 오류가 발생하는 경우

[Windows] Chocolatey upgrade