WEB/JavaScript

자바스크립트 클래스 그리고 상속

AlrepondTech 2015. 3. 19. 21:36
반응형

 

 

 

=================================

=================================

=================================

 

 

 

 

출처: http://m.mkexdev.net/m/post/214

 

객체 지향 언어의 면모를 여실히 보여주는 자바스크립트 상속! 다형성!

좋구먼~ ㅎㅎㅎ

 

넌 너무 유연해~~

 

var Polygon = function(){

    var self = this;

    self.type = "Polygon";    

    self.commonDo = function(){

        console.log("commonDoing...");

    };

    self.draw = function(){

        console.log("draw " + self.type);

    };

};

 

var Square = function(){

  var self = this;

  self.type = "Square";

  self.draw = function(){                              //오버라이딩

      console.log("draw " + self.type); 

  };

  self.squareDoing = function(){

    console.log("squareleDoing...");  

  }

};

Square.prototype = new Polygon();         //상속

 

 

var Triangle = function(){

  var self = this;

  self.type = "Triangle";

  self.draw = function(){                              //오버라이딩         

      console.log("draw " + self.type);

  };

  self.triangleDoing = function(){

    console.log("triangleDoing...");  

  }

};

Triangle.prototype = new Polygon();       //상속

 

....

 

var obj1 = new Square();

obj1.commonDo();

obj1.draw();     

obj1.squareDoing();       

 

var obj2 = new Triangle();

obj2.commonDo();

obj2.draw();

obj2.triangleDoing();          

 

console.log(obj1 instanceof Polygon);

console.log(obj2 instanceof Polygon);

 

 

prototype.js를 이용하면 보다 가독성 높은 상속 코드를 구현할 수 있다. 아래 코드는 prototype.js를 사용해서 이전 코드와 동일한 클래스 및 상속 구조를 구현한다

var Polygon = Class.create({

    initialize: function(){

        this.type = "Polygon";

    },  

    commonDo : function(){

        console.log("commonDoing...");

    },

    draw : function(){

        console.log("draw " + this.type);

    }

});

 

var Square = Class.create(Polygon,{

  initialize: function(){

        this.type = "Square";

  },  

  draw : function(){               

      console.log("draw " + this.type); 

  },

  squareDoing : function(){

    console.log("squareleDoing...");  

  }

});

 

 

var Triangle = Class.create(Polygon,{

  initialize: function(){

        this.type = "Triangle";

  },

  draw : function(){               

      console.log("draw " + this.type); 

  },

  triangleDoing : function(){

    console.log("triangleDoing...");  

  }

});

 

 

 

=================================

=================================

=================================

 

 

 

출처: http://waky.blog.me/144127494

 

 

소개 
자바스크립트는 문법적인 측면에서 봤을 때, 매우 유연한 객체지향언어이다. 이번 글에서 여러분은 객체를 정의하고 생성하는 세 가지 방법에 대해서 알 수 있을 것이다. 이미 여러분이 자신만의 방법을 갖고 있다고 할지라도 다른 사람의 코드를 읽기 위해서라도 다른 방법들에 대해 알아두는 것이 좋다.
자바 스크립트에서는 클래스가 없다. 함수가 클래스로서 사용될 수 있지만, 일반적으로 자바스크립트는 클래스가 없는(class-less) 언어이다. 자바스크립트에서는 모든 것이 객체이다. 상속의 측면에서 전통적인 언어와는 달리 클래스가 아니라, 객체는 객체로부터 상속을 받는다.

1. 함수 사용 
이 방법은 가장 일반적인 방법중 하나일 것이다. 일반적인 자바스크립트 함수를 정의하고나서 new 키워드를 사용하여 객체를 생성한다. 프로퍼티와 메소드를 정의하기 위해서 다음 예제에서 보는 것처럼 this를 사용하면 된다.

 

function Apple (type) {
    this.type = type;
    this.color = "red";
    this.getInfo = getAppleInfo;
}
  
// anti-pattern! keep reading...
function getAppleInfo() {
    return this.color + ' ' this.type + ' apple';
}

다음 예제처럼, Apple 생성자를 사용하여 객체를 생성하고 프로퍼티를 설정하고 메소드를 호출할 수 있다.

 

var apple = new Apple('macintosh');
apple.color = "reddish";
alert(apple.getInfo());
 

1.1 내부적으로 정의된 메소드


위 예제에서는 Apple “클래스”의 getInfo() 메소드는 별개의 getAppleInfo() 함수로 정의되었다. 이는 잘 동작하는 코드이지만 결점을 가지고 있다. 이런 식으로 함수 다수를 정의하게 되면, 그것들은 모두 전역 네임 스페이스에 들어가게 되는데, 이는 이름 충돌이 일어날 수도 있다. 전역 네임스페이스의 오염을 방지하려면, 메소드를 아래와 같이 생성자 내부에 정의해야 한다.

 

function Apple (type) {
    this.type = type;
    this.color = "red";
    this.getInfo = function() {
        return this.color + ' ' this.type + ' apple';
    };
}
 

이렇게 하면, 문법적으로 아무런 변화 없이 프로퍼티와 메소드를 사용할 수 있다.

 

1.2 프로토타입에 추가된 메소드

1.1의 결점은 getInfo() 메소드가 새로운 객체를 생성할 때마다 매번 다시 만들어진다는 것이다. 때로는 이것이 개발자가 원하는 것일 수도 있지만, 이는 드문 일이다. 이보다 더 가벼운 방식은 getInfo()메소드를 생성자의 프로토타입에 추가하는 것이다.

 

function Apple (type) {
    this.type = type;
    this.color = "red";
}
  
Apple.prototype.getInfo = function() {
    return this.color + ' ' this.type + ' apple';
};
 

다시 한번 말하지만, 여러분은 1 과 1.1 에서와 똑같이 새 객체를 사용할 수 있다.

 

2. 객체 기본문법(literals) 사용

 

기본문법을 사용하면 자바스크립트에서 객체나 배열을 더 간단하게 정의할 수 있다. 빈 객체를 하나 생성하기 위해서는 다음과 같이 하면 된다.

객체를 만드는 “일반적인” 방법인 아래 방법 대신에,

 

var o = new Object();
 

아래와 같이 할 수 있다.

 

var o = {};

 

빈 배열은 아래와 같은 방법 대신에,

var a = new Array();

아래와 같이 할 수 있다.

var a = [];

 

이처럼 클래스 만드는 방식과 비슷한 일을 하지 않고, 객체를 바로 생성할 수 있다. 아래 예제는 위 예제와 같은 기능을 하는데, 단지 객체 기본 문법만을 사용했다.

var apple = {
    type: "macintosh",
    color: "red",
    getInfo: function () {
        return this.color + ' ' this.type + ' apple';
    }
}

이 경우는 클래스의 인스턴스를 만들 필요가 없고, 만들 수도 없다. 이미 존재하기 때문이다. 따라서, 단순이 이 인스턴스를 아래와 같이 사용하기만 하면 된다.

apple.color = "reddish";
alert(apple.getInfo());

  

이러한 객체를 때로는 싱글톤이라고 불리우기도 한다. 자바와 같은 전통적인 언어에서는 항상 해당 클래스의 인스턴스를 하나만 가질 수 있고 더 이상의 객체를 만들 수 없다. 하지만, 자바스크립트에서 객체는 이미 시작할 때 부터 싱글톤이기 때문에, 이러한 개념은 의미가 없다.

 

3. 함수를 이용한 싱글톤


세 번째 방법은 위 두가지 방법을 합친 것이다. 싱글톤 객체를 정의하기 위해 함수를 사용하는 것이다.

var apple = new function() {
    this.type = "macintosh";
    this.color = "red";
    this.getInfo = function () {
        return this.color + ' ' this.type + ' apple';
    };
}

위 예제는 1.1과 매우 유사하다. 그러나 객체를 사용하는 방법에 관해서는 2와 같다.

apple.color = "reddish";
alert(apple.getInfo());

 

 

new function(){} 은 동시에 두가지 일을 하는데, 하나는 함수를 정의하는 것이고, 다른 하나는 new를 가지고 생성하는 것이다. 이에 익숙하지않다면, 조금 혼란스러울 수도 있다. 하지만 이것은 선택 사항일 뿐이다.

 

 

 

 

 

 

=================================

=================================

=================================

 

 

출처: http://cusmaker.tistory.com/160

 


<script>

var myClass = function(){

//private field

var age = 26;

var name = '재욱';

 

//public field

this.phone = '010-1234-9999';

this.email = 'abcdefg@naver.com';

 

//private method

var getAge = function(){

return age;

}

 

//public method

this.getName = function(){

//return getAge(); //private method 호출가능

//return this.email; //public field 참조가능

return name; //private field 참조가능

}

};


var o = new myClass();

console.log(o.name); //undefined

console.log(o.phone); //010-4404-6492

console.log(o.getName()); //재욱

console.log(o.getAge()); //Uncaught TypeError: Object [object Object] has no method 'getAge' 

</script>

 

위 방법은 함수 표현식을 통한 클래스 형상화를 한것입니다. 함수 선언식으로 해도 결과는 동일합니다.

■ public

this 키워드를 통해 생성하는 필드와 메소드는 모두 public 으로 사용하고, 접근도 가능합니다.

 

■ private

var 선언문을 통해 작성된 필드와 메소드는 모두 private으로 사용하고, 외부에서 접근이 불가능합니다.

 

■ 생성자

자바스크립트의 생성자는 function 그 자체를 의미합니다. new 키워드를 붙여 오브젝트를 인스턴스화 시킬때 constructor 필드는 함수 자체를 가르키고있기때문에 특별한 생성자를 구축할수가 없습니다.

또한 해당 필드를 수정한다한들 new 연산시 다시금 자기자신을 돌아보게 하기때문에 생성자에 대한 처리를 둘 수 없습니다.

일반적인 경우는 이런식으로 처리합니다.

 

var test = function(param1 , param2){

var age = param1;

var name = param2;

this.getInfo = function(){

return [age  , name];

}

}

 

var t = new test(26 , "ㅇㅅㅇ");

console.log(t.getInfo());

 

 

함수파라미터를 넘긴다는 의미로 위와같이 작성할 수 있습니다.

또다른 방법으로는 즉시수행함수를 통한 좀더 그럴듯한 셋팅방법이 있습니다만, 쓸때없이 메모리를 낭비하기때문에 위와같은 방법을 권합니다.

 

■ 소멸자

자바스크립트는 소멸자가 없습니다. ㅋㅋ 소멸자는 어떻게 구현해보려해도 되질않습니다. 

 

 

이정도로 클래스의 기본적인 부분을 마치며 다음에는 좀더 심오한 prototype에 대해 작성해볼까합니다 ㅇㅅㅇ

 

 

 

=================================

=================================

=================================

 

 

출처: http://jw9651.blog.me/220081997980

 

한참 스터디 중인 자바스크립트에서 클래스를 상속하는 방법에 대해서 정리해 보겠습니다.
배우는중이라 틀린 부분이 있다면 댓글로 알려주시면 감사하겠습니다.^^

자바스크립트책을 조금 읽어보신 분들은 자바스크립트에는 클래스가 없다는 것을 알고계실 겁니다. 자바스크립트에는 생성자함수만 있는데 부모 생성자함수를 자식 생성자함수가 상속받아서 사용하기위해서 두가지 방법이 있습니다.  방법은 아래와 같습니다.

첫번째 방법, 자식 생성자함수로 생성한 객체의 __proto__프로퍼티가 가르키는 생성자함수의 prototype 객체에 부모 생성자함수(함수가아닌 new를 통해 생성되는 객체)를 할당하는 방법입니다.
( 부모 생성자함수의 this가 참조하는 멤버들과 __proto__프로퍼티가 가르키는 prototype객체를 할당 )

var Parent = function () { this.name = "adam"; }; var Child = function () { this.name = "adam"; }; // 상속 구현 Child.prototype = new Parent;

위와 같은 방법으로 상속을 구현하면 Parent의 this로 참조되는 멤버들이 Child에 복사가 아닌 참조가 일어납니다. 따라서 hasOwnProperty를 돌려보면 Child에서 해당프로퍼티가 없기 때문에 아래와 같은 결과를 확인하실 수 있습니다.

var p = new Parent(); var c = new Child(); p.hasOwnProperty(\'name\'); // true c.hasOwnProperty(\'name\'); // false

이런 패턴의 경우 부모 생성자함수의 this가 참조하는 멤버들을 사용할 수 있고 prototype 체인 추적이 가능하지만 부모 생성자함수로 인자를 넘길 방법이 없다는 단점이 있습니다.

위 문제를 해결하기 위해서 두번째 상속방법인 apply,call 등을 사용하여 생성자를 빌려올 수 있으며, 생성자 빌려오기를 통해 다중 상속구현이 가능합니다.

var Child = function () {     Parent.apply ( this, arguments );     God.apply ( this, arguments ); };

이경우에는 부모의 생성자함수에 파라미터 전달이 가능하지만 부모 생성자함수의 prototype에 접근이 불가능하기 때문에 아래와 같이 작성하여 해결할 수 있습니다.

var Child = function () {     Parent.apply ( this, arguments ); }; Child.prototype = new Parent();

위와같이 작성하면 자식객체는 부모가 가진 프로퍼티의 복사본을 가지고 prototype 참조를 물려받으면서 파라미터 전달도 가능하지만 부모 생성자함수가 자식 생성자함수에서 한번, prototype에 할당시 한번으로 두번 호출된다는 단점이 있습니다.

(Child.prototype객체가 부모 생성자함수의 prototype만 참조하도록 하면 자식객체에서 부모객체로 prototype체인 추적이 가능합니다.)

var Child = function () {     Parent.apply ( this, arguments ); }; Child.prototype = Parent.prototype;

위와같이 작성하면 자식 생성자함수의 prototype 객체는 부모 생성자함수의 this로 참조되는 멤버와 부모 생성자함수의 prototype에 접근할 수 있게됩니다. 하지만 여기에도 단점이 있는데 상속체인의 어딘가에서 prototype을 수정할 경우 prototype체인상의 모든 객체에 영향을 미칩니다. 해당 문제는 아래와 같은 방법으로 해결할 수 있습니다.

var F = function(){}; F.prototype = Parent.prototype; Child.prototype = new F();

임시생성자 ’F’ 를 만들어 부모와 자식객체의 prototype간의 링크를 끊어주는 것 입니다.  이제 상속 구현은 다 되었습니다.

추가로 Child.prototype.constructor를 Child로 선언해 줍니다. 아래와 같이 Child로 인스턴스를 생성할경우 인스턴스의 constructor는 Child일거라고 예상되지만 실제로는 Object를 반환하였습니다. 따라서 Child.prototype.constructor를 Child로 선언해줍니다. (생활코딩의 김중훈님께서 알려주셨습니다.)

var c = new Child(); c.constructor // Object Child.prototype.constructor = Child; c.constructor // Child

 

 

 

상위클래스 저장 및 생성자 포인터 재설정을.. 더정리하자..ㅋ

 

 

 

 

=================================

=================================

=================================

 

 

 

출처: http://redpumpkin.net/220252765398

 

자바스크립트에서 클래스 사용하기
---1-1
//첫번째, 함수를 이용하는 방법입니다.function Coffie(price, sugar, coffieBean){  this.price = price | 0;  this.sugar = sugar | 0;  this.coffieBean = coffieBean | 0;  this.getInfo = function()  {    return {price: this.price, sugar: this.sugar, coffieBean: this.coffieBean};  }}
//usagevar coffieObject = new Coffie(2500, 10, 10);console.log(coffieObject.getInfo());
1-2

//1-1의 단점을 수정합니다. function Coffie(price, sugar, coffieBean) {   this.price = price | 0;   this.sugar = sugar | 0;   this.coffieBean = coffieBean | 0; } Coffie.prototype.getInfo = function() {   return {price: this.price, sugar: this.sugar, coffieBean: this.coffieBean}; }  //usage var coffieObject = new Coffie(2500, 10, 10); console.log(coffieObject.getInfo());
2
//객체를 이용하는 방법입니다, 싱글톤 패턴. var Coffie = {   price: 0,   sugar: 0,   coffieBean: 0,   getInfo: function()   {     return {price: this.price, sugar: this.sugar, coffieBean: this.coffieBean};   } }  //usage Coffie.price = 2500; console.log(Coffie.getInfo());

 

 

 

 

=================================

=================================

=================================

 

 

출처: http://blog.naver.com/diceworld/220203934701

 

 

 

 

자바스크립트 클래스 선언방법



   function [클래스명]([매개변수]){
   }

 

 [참고사항] 자바스크립트 클래스

 



   
자바스크립트에 클래스를 생성하는 방법은 여러가지가 있는데    크게 리터럴을 이용하는 방법과 함수를 이용하는 방법으로 나뉘어집니다.   여기서는 함수를 이용하는 방법을 기준으로 구성하였습니다.

 

 

자바스크립트 객체 인스턴스 생성방법



   var [인스턴스명] = new [클래스명]([매개변수]);

 

 

 

 

 

 

자바스크립트 프로퍼티 생성방법



   function [클래스명]([매개변수]){
      this.[프로퍼티명] = [프로퍼티값];
   }

 

 

 

 

 

자바스크립트 프로퍼티 사용방법



   var [인스턴스명] = new [클래스명]([매개변수]);
   [인스턴스명].[프로퍼티명] = [프로퍼티값];

 

 

 

 

 

 

자바스크립트 메서드 생성방법 (클래스 내부 정의)



   function [클래스명]([매개변수]){
      this.[메서드명] = function([메서드 매개변수]){
         [소스코드];
      }
   }

 

 

 

 

 

자바스크립트 메서드 생성방법 (prototype 을 이용하여 정의)



   function [클래스명]([매개변수]){
   }
 


   [클래스명].prototype.[메서드명] = function([매개변수]){
      [소스코드];
   };

 

 

 

 

자바스크립트 메서드 호출방법



   var [인스턴스명] = new [클래스명]([매개변수]);
   [인스턴스명].[메서드명]([메서드 매개변수]);

 

 

 

 

 - 예제 1



   
아래와 같은 클래스를 생성하시오.

 

이름 내용
클래스명 Class
매개변수 없음
프로퍼티 no = 1;
메서드 document.write(no);
생성자 없음

 

 - 예제 1 소스



   function Class(){
      this.no = 1;
 
      this.printNo = function(){
         
document.write(this.no + "<br>");
      }
   }

 - 예제 2



   
예제1에서 생성한 클래스를 이용하여 객체를 생성한 후 프로퍼티 no 의 값을 10으로 변경하고 printNo 메서드를 호출하시오.

 

 - 예제 2 소스



   
var classObj = new Class();
   classObj.no = 10;
   classObj.printNo();

   결과


   10
 

 

 - 예제 3



   
아래와 같은 클래스를 생성한 후 매개변수를 7로하여 객체를 생성하시오.

 

이름 내용
클래스명 Class2
매개변수 no1
프로퍼티 no2 = 8;
메서드 document.write(no1 * no2);
생성자 메서드 실행

 

 - 예제 3 소스



   function Class(no1){
      this.no1 = no1;      this.no2 = 8;
 
      this.printVal = function(){
         
document.write(this.no1 * this.no2 + "<br>");
      }
      printVal();
   }
 
   
var classObj = new Class(7);


   결과


   56

 

 

 

=================================

=================================

=================================

 

 

 

출처: http://blog.naver.com/lobolook/220166273791

 

클래스 (& 모듈화)

자바스크립트에선 new 키워드는 사용을 권장하지 않는다.

클래스라는 것은 자바스크립트방식이 아니라는 것에서 비난을 받는다. (구조는 고려하지 말아야 한다고 생각)

 

자바스크립트는 클래스 정의 대신 new키워드를 이용해 새 인스턴스를 만들수 있다.

-- 사용례 --

var Person = function(name) {

this.name = name;

};

 

// Person을 인스턴스화한다.

var alice = new Person('송혜교');

 

// 인스턴스 확인

assert( alice instanceof Person );                // 기본 내장함수가 아닌, 사용자가 테스팅하려 만든 함수이다. 이후 포스트에 언급되어 있다.

 

 

 

 

-- 오브젝트 프로퍼티 추가 --

Person.find = fucntion(id){ /* ..... */};

 

var person = Person.find(1);

 

 

-- 인스턴스 함수를 생성자 함수에 추가 (생성자의 prototype이 필요) --

Person.prototype.breath = fucntion(){ /* ..... */};

 

var person = new Person;

person.breath();

 

 

 

 

-- 일반적으로 클래스 prototype을 fn이라는 별칭으로 사용(jQuery 플러그인에서는 fn이라는 별칭을 사용하여 jQuery.fn에 함수를 추가) --

Person.fn = Person.prototype;

 

Person.fn.run =  fucntion(){ /* ..... */};

 

 

 

 

아래는 그냥 이렇다고.

 

-- 클래스 라이브러리에 메소드 추가. 정적, 동적 프로퍼티를 한눈에 (추가한걸) 파악하기 위해 extend(), include() 를 활용 ---

var Class = function(){

    var klass = function(){

        this.init.apply(this, arguments);

    };

 

    klass.prototype.init = function(){};

 

    // 프로토타입의 단축형

    klass.fn = klass.prototype;

 

    // 클래스의 단축형

    klass.fn.parent = klass;

 

    // 클래스 프로퍼티 추가

    klass.extend = function(obj){

        var extended = obj.extended;

        for(var i in obj){

            klass[i] = obj[i];

        }

        if( extended) {

            extended(klass);

        }

    };

 

    // 인스턴스 프로퍼티 추가

    klass.include = function(obj){

        var included = obj.included;

        for(var i in obj){

            klass.fn[i] = obj[i];

        }

        if( included) {

            included(klass);

        }

    }

};

 

 

 

 

 

 

 

------------------------------------------------------------------------------

* 모듈 패턴

전역 명칭공간 남발 방지, 로직을 캡슐화 ---> 익명함수덕분

(function(){

    /* .... */

})();

위 처럼 괄호로 감싸지 않으면 js가 구문을 제대로 해석하지 못 할 수 있다.

 

 

 

 

전역 임포트

 

전역 임포트 존재이유 - 

(애플리케이션의 전역 변수는 이용할 수 있다.)

모듈이 커지다보면 어떤 전역변수를 모듈에서 사용하는지 명확하지 않을 수 있다.

암묵적으로 전역변수를 사용시 (어떤 범위의 변수인지 명시하지 않고 변수명을 사용하는 상황), 자바스크립트 인터프리터에서 범위 체인을 이용해 변수의 범위를 계산해야 하므로 해석에 시간이 걸린다.

 

위의 문제를 해결하는 방법은

익명함수에 globals를 파라미터로 넘겨줌으로써 전역 변수를 코드에 임포트 할 수 있고, 고로 암묵적 글로벌 사용시 보다 명확하고 빠르게 동작한다.

 

--- 전역 임포트 ----

(function($){

    /* .... */

})(jQuery);

 

설명 : 전역 변수 jQuery의 별칭을 $로 사용해서 모듈로 임포트.

그러면 모듈 내에서 어떤 전역 변수를 가르키는지 명확해지므로 전역 변수 탐색시간이 줄어든다.

.... jQuery의 $ 단축형을 사용하는 방법의 정석으로, 이 방식은 다른 라이브러리와 충돌을 피할 수 있다.

 

 

 

=================================

=================================

=================================

 

 

 

 

반응형