μΉ΄ν…Œκ³ λ¦¬ 보관물: Javascript

Javascript

JavaScript둜 클래슀λ₯Ό μ •μ˜ν•˜λŠ” 데 μ‚¬μš©ν•  μˆ˜μžˆλŠ” κΈ°μˆ μ€ 무엇이며 κ·Έ 상좩 κ΄€κ³„λŠ” λ¬΄μ—‡μž…λ‹ˆκΉŒ? μ„ ν˜Έν•©λ‹ˆλ‹€. JavaScript둜

ν˜„μž¬ μž‘μ—…μ€‘μΈ 것과 같은 λŒ€κ·œλͺ¨ ν”„λ‘œμ νŠΈμ—μ„œ OOPλ₯Ό μ‚¬μš©ν•˜λŠ” 것을 μ„ ν˜Έν•©λ‹ˆλ‹€. JavaScript둜 μ—¬λŸ¬ 클래슀λ₯Ό λ§Œλ“€μ–΄μ•Όν•˜μ§€λ§Œ μ‹€μˆ˜ν•˜μ§€ μ•Šμ€ 경우 적어도 두 κ°€μ§€ λ°©λ²•μœΌλ‘œ μˆ˜ν–‰ ν•  수 μžˆμŠ΅λ‹ˆλ‹€. ꡬ문은 무엇이며 μ™œ 그런 μ‹μœΌλ‘œ μˆ˜ν–‰λ©λ‹ˆκΉŒ?

적어도 μ²˜μŒμ—λŠ” 타사 라이브러리λ₯Ό μ‚¬μš©ν•˜κ³  μ‹Άμ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
λ‹€λ₯Έ 닡변을 찾으렀면 JavaScript둜 객체 μ§€ν–₯ ν”„λ‘œκ·Έλž˜λ°μ— λŒ€ν•΄ μ„€λͺ…ν•˜λŠ” JavaScript둜 객체 μ§€ν–₯ ν”„λ‘œκ·Έλž˜λ° , 1 λΆ€ : 상속-Doc JavaScript 기사λ₯Ό μ°Ύμ•˜μŠ΅λ‹ˆλ‹€ . 상속을 μˆ˜ν–‰ν•˜λŠ” 더 쒋은 방법이 μžˆμŠ΅λ‹ˆκΉŒ?



λ‹΅λ³€

μ™ΈλΆ€ 라이브러리λ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³  μˆ˜ν–‰ν•˜λŠ” 방법은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

// Define a class like this
function Person(name, gender){

   // Add object properties like this
   this.name = name;
   this.gender = gender;
}

// Add methods like this.  All Person objects will be able to invoke this
Person.prototype.speak = function(){
    alert("Howdy, my name is" + this.name);
};

// Instantiate new objects with 'new'
var person = new Person("Bob", "M");

// Invoke methods like this
person.speak(); // alerts "Howdy, my name is Bob"

μ‹€μ œ 닡변은 그보닀 훨씬 더 λ³΅μž‘ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, JavaScriptμ—λŠ” ν΄λž˜μŠ€μ™€ 같은 것이 μ—†μŠ΅λ‹ˆλ‹€. JavaScriptλŠ” prototype기반 상속 체계λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€ .

λ˜ν•œ JavaScriptμ—λŠ” ν΄λž˜μŠ€μ™€ μœ μ‚¬ν•œ κΈ°λŠ₯을 μ œκ³΅ν•˜λŠ” 고유 ν•œ μŠ€νƒ€μΌμ„ κ°€μ§„ μΈκΈ°μžˆλŠ” JavaScript λΌμ΄λΈŒλŸ¬λ¦¬κ°€ 많이 μžˆμŠ΅λ‹ˆλ‹€. 적어도 ν”„λ‘œν†  νƒ€μž… κ³Ό jQuery λ₯Ό ν™•μΈν•˜κ³  싢을 것이닀 .

이 쀑 β€œμ΅œκ³ β€λ₯Ό κ²°μ •ν•˜λŠ” 것은 Stack Overflowμ—μ„œ κ±°λ£©ν•œ μ „μŸμ„ μ‹œμž‘ν•˜λŠ” 쒋은 λ°©λ²•μž…λ‹ˆλ‹€. 더 큰 JavaScriptκ°€ λ§Žμ€ ν”„λ‘œμ νŠΈλ₯Ό μ‹œμž‘ν•˜λŠ” 경우 μΈκΈ°μžˆλŠ” 라이브러리λ₯Ό 배우고 κ·Έ λ°©μ‹λŒ€λ‘œ μˆ˜ν–‰ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€. μ €λŠ” ν”„λ‘œν†  νƒ€μž… μ‚¬λžŒμ΄μ§€λ§Œ μŠ€νƒ μ˜€λ²„ν”Œλ‘œλŠ” jQuery에 μ˜μ‘΄ν•˜λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€.

μ™ΈλΆ€ λΌμ΄λΈŒλŸ¬λ¦¬μ— μ˜μ‘΄ν•˜μ§€ μ•Šκ³  β€œν•œ κ°€μ§€ λ°©λ²•β€λ§ŒμžˆλŠ” ν•œ, λ‚΄κ°€ μ“΄ 방식은 거의 λΉ„μŠ·ν•©λ‹ˆλ‹€.


λ‹΅λ³€

JavaScriptμ—μ„œ 클래슀λ₯Ό μ •μ˜ν•˜λŠ” κ°€μž₯ 쒋은 방법은 클래슀λ₯Ό μ •μ˜ν•˜μ§€ μ•ŠλŠ” κ²ƒμž…λ‹ˆλ‹€.

μ§„μ‹¬μœΌλ‘œ.

μ—¬λŸ¬ κ°€μ§€ λ°©ν–₯의 객체 μ§€ν–₯이 있으며 그쀑 μΌλΆ€λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

  • 클래슀 기반 OO (Smalltalkμ—μ„œ 처음 μ†Œκ°œ)
  • ν”„λ‘œν†  νƒ€μž… 기반 OO (μžμ²΄μ—μ„œ 처음 μ†Œκ°œ)
  • λ©€ν‹° λ©”μ†Œλ“œ 기반 OO (CommonLoopsκ°€ 처음 λ„μž… ν•œ 것 κ°™μŠ΅λ‹ˆλ‹€.)
  • μˆ μ–΄ 기반 OO (λͺ¨λ¦„)

그리고 μ•„λ§ˆ λ‚΄κ°€ λͺ¨λ₯΄λŠ” λ‹€λ₯Έ μ‚¬λžŒλ“€.

JavaScriptλŠ” ν”„λ‘œν†  νƒ€μž… 기반 OOλ₯Ό κ΅¬ν˜„ν•©λ‹ˆλ‹€. ν”„λ‘œν†  νƒ€μž… 기반 OOμ—μ„œλŠ” 클래슀 ν…œν”Œλ¦Ώμ—μ„œ μΈμŠ€ν„΄μŠ€ν™”λ˜λŠ” λŒ€μ‹  λ‹€λ₯Έ 개체λ₯Ό λ³΅μ‚¬ν•˜μ—¬ μƒˆ 개체λ₯Ό λ§Œλ“€κ³  λ©”μ„œλ“œλŠ” 클래슀 λŒ€μ‹  κ°œμ²΄μ— 직접 μ‘΄μž¬ν•©λ‹ˆλ‹€. 상속은 μœ„μž„μ„ 톡해 μˆ˜ν–‰λ©λ‹ˆλ‹€. 객체에 λ©”μ„œλ“œ λ‚˜ μ†μ„±μ΄μ—†λŠ” 경우 ν”„λ‘œν†  νƒ€μž… (즉, 볡제 된 객체)κ³Ό ν”„λ‘œν†  νƒ€μž…μ˜ ν”„λ‘œν†  νƒ€μž… 등을 μ°ΎμŠ΅λ‹ˆλ‹€.

λ‹€μ‹œ 말해, μˆ˜μ—…μ΄ μ—†μŠ΅λ‹ˆλ‹€.

μžλ°” μŠ€ν¬λ¦½νŠΈλŠ” μ‹€μ œλ‘œ κ·Έ λͺ¨λΈμ— λŒ€ν•œ ν›Œλ₯­ν•œ μ‘°μ •μ΄μžˆλ‹€ : μƒμ„±μž. κΈ°μ‘΄ 객체λ₯Ό λ³΅μ‚¬ν•˜μ—¬ 객체λ₯Ό λ§Œλ“€ μˆ˜μžˆμ„λΏλ§Œ μ•„λ‹ˆλΌ β€œμ–‡μ€ κ³΅κΈ°κ°€μ—†λŠ”β€κ°μ²΄λ₯Ό λ§Œλ“€ μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. newν‚€μ›Œλ“œλ₯Ό μ‚¬μš© ν•˜μ—¬ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄ ν•΄λ‹Ή ν•¨μˆ˜κ°€ μƒμ„±μžκ°€λ˜κ³  thisν‚€μ›Œλ“œλŠ” ν˜„μž¬ 객체λ₯Ό 가리 ν‚€μ§€ μ•Šκ³  μƒˆλ‘œ μž‘μ„±λœ β€œλΉˆβ€κ°μ²΄λ₯Ό 가리 ν‚΅λ‹ˆλ‹€. λ”°λΌμ„œ μ›ν•˜λŠ” λ°©μ‹μœΌλ‘œ 개체λ₯Ό ꡬ성 ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŸ¬ν•œ λ°©μ‹μœΌλ‘œ JavaScript μƒμ„±μžλŠ” κΈ°μ‘΄ 클래슀 기반 OOμ—μ„œ 클래슀 μ—­ν•  쀑 ν•˜λ‚˜λ₯Ό μˆ˜ν–‰ ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μƒˆ 객체의 ν…œν”Œλ¦Ώ λ˜λŠ” 청사진 μ—­ν• μ„ν•©λ‹ˆλ‹€.

이제 JavaScriptλŠ” 맀우 κ°•λ ₯ν•œ μ–Έμ–΄μ΄λ―€λ‘œ μ›ν•˜λŠ” 경우 JavaScript λ‚΄μ—μ„œ 클래슀 기반 OO μ‹œμŠ€ν…œμ„ μ‰½κ²Œ κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ Java κ°€ν•˜λŠ” 방식이 μ•„λ‹ˆλΌ μ‹€μ œλ‘œ ν•„μš”ν•œ κ²½μš°μ—λ§Œμ΄ μž‘μ—…μ„ μˆ˜ν–‰ν•΄μ•Όν•©λ‹ˆλ‹€.


λ‹΅λ³€

ES2015 μˆ˜μ—…

ES2015 μ‚¬μ–‘μ—μ„œλŠ” ν”„λ‘œν†  νƒ€μž… μ‹œμŠ€ν…œμ— λΉ„ν•΄ λ‹¨μˆœν•œ 클래슀 ꡬ문을 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

class Person {
  constructor(name) {
    this.name = name;
  }
  toString() {
    return `My name is ${ this.name }.`;
  }
}

class Employee extends Person {
  constructor(name, hours) {
    super(name);
    this.hours = hours;
  }
  toString() {
    return `${ super.toString() } I work ${ this.hours } hours.`;
  }
}

ν˜œνƒ

μ£Όμš” 이점은 정적 뢄석 도ꡬ가이 ꡬ문을보닀 μ‰½κ²Œ β€‹β€‹νƒ€κ²ŸνŒ… ν•  수 μžˆλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. λ˜ν•œ 클래슀 기반 μ–Έμ–΄λ₯Ό μ‚¬μš©ν•˜λŠ” λ‹€λ₯Έ μ‚¬λžŒλ“€μ΄ ν•΄λ‹Ή μ–Έμ–΄λ₯Ό 폴리 κΈ€λ‘―μœΌλ‘œ μ‚¬μš©ν•˜λŠ” 것이 더 μ‰½μŠ΅λ‹ˆλ‹€.

κ²½κ³ 

ν˜„μž¬ μ œν•œ μ‚¬ν•­μ—μ£Όμ˜ν•˜μ‹­μ‹œμ˜€. 개인 속성을 μ–»μœΌλ €λ©΄ Symbols λ˜λŠ” WeakMaps μ‚¬μš©μ— μ˜μ‘΄ν•΄μ•Όν•©λ‹ˆλ‹€ . ν–₯ν›„ λ¦΄λ¦¬μŠ€μ—μ„œλŠ” μ΄λŸ¬ν•œ λˆ„λ½ 된 κΈ°λŠ₯을 ν¬ν•¨ν•˜λ„λ‘ ν΄λž˜μŠ€κ°€ ν™•μž₯ 될 κ°€λŠ₯성이 λ†’μŠ΅λ‹ˆλ‹€.

μ§€μ›ν•˜λ‹€

λΈŒλΌμš°μ € 지원 은 ν˜„μž¬λ‘œμ„œλŠ” μ’‹μ§€ μ•Šμ§€λ§Œ (IEλ₯Ό μ œμ™Έν•œ 거의 λͺ¨λ“  μ‚¬λžŒμ΄ 지원), 이제 Babel κ³Ό 같은 트랜슀 νŒŒμΌλŸ¬μ—μ„œ μ΄λŸ¬ν•œ κΈ°λŠ₯을 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€ .

μžμ›


λ‹΅λ³€

μ €λŠ” Daniel X. Moore β€˜sλ₯Ό μ„ ν˜Έν•©λ‹ˆλ‹€ {SUPER: SYSTEM}. μ΄λŠ” μ‹€μ œ μΈμŠ€ν„΄μŠ€ λ³€μˆ˜, νŠΉμ„± 기반 상속, 클래슀 계측 및 ꡬ성 μ˜΅μ…˜κ³Ό 같은 이점을 μ œκ³΅ν•˜λŠ” ν•™λ¬Έμž…λ‹ˆλ‹€. μ•„λž˜ μ˜ˆμ œλŠ” μ‹€μ œ μΈμŠ€ν„΄μŠ€ λ³€μˆ˜μ˜ μ‚¬μš©μ„ λ³΄μ—¬μ€λ‹ˆλ‹€. 이것이 κ°€μž₯ 큰 μž₯점이라고 μƒκ°ν•©λ‹ˆλ‹€. μΈμŠ€ν„΄μŠ€ λ³€μˆ˜κ°€ ν•„μš”ν•˜μ§€ μ•Šκ³  곡개 λ˜λŠ” 개인 λ³€μˆ˜μ—λ§Œ λ§Œμ‘±ν•˜λ©΄ 더 κ°„λ‹¨ν•œ μ‹œμŠ€ν…œμ΄μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.

function Person(I) {
  I = I || {};

  Object.reverseMerge(I, {
    name: "McLovin",
    age: 25,
    homeState: "Hawaii"
  });

  return {
    introduce: function() {
      return "Hi I'm " + I.name + " and I'm " + I.age;
    }
  };
}

var fogel = Person({
  age: "old enough"
});
fogel.introduce(); // "Hi I'm McLovin and I'm old enough"

μ™€μš°, 그것은 μ‹€μ œλ‘œ κ·Έλ‹€μ§€ μœ μš©ν•˜μ§€λŠ” μ•Šμ§€λ§Œ μ„œλΈŒ 클래슀λ₯Ό μΆ”κ°€ν•˜λŠ” 것을 μ‚΄νŽ΄λ³΄μ‹­μ‹œμ˜€.

function Ninja(I) {
  I = I || {};

  Object.reverseMerge(I, {
    belt: "black"
  });

  // Ninja is a subclass of person
  return Object.extend(Person(I), {
    greetChallenger: function() {
      return "In all my " + I.age + " years as a ninja, I've never met a challenger as worthy as you...";
    }
  });
}

var resig = Ninja({name: "John Resig"});

resig.introduce(); // "Hi I'm John Resig and I'm 25"

또 λ‹€λ₯Έ μž₯점은 λͺ¨λ“ˆκ³Ό νŠΉμ„± 기반 상속 κΈ°λŠ₯μž…λ‹ˆλ‹€.

// The Bindable module
function Bindable() {

  var eventCallbacks = {};

  return {
    bind: function(event, callback) {
      eventCallbacks[event] = eventCallbacks[event] || [];

      eventCallbacks[event].push(callback);
    },

    trigger: function(event) {
      var callbacks = eventCallbacks[event];

      if(callbacks && callbacks.length) {
        var self = this;
        callbacks.forEach(function(callback) {
          callback(self);
        });
      }
    },
  };
}

person 클래슀λ₯Ό κ°–λŠ” μ˜ˆμ—λŠ” 바인딩 κ°€λŠ₯ν•œ λͺ¨λ“ˆμ΄ μžˆμŠ΅λ‹ˆλ‹€.

function Person(I) {
  I = I || {};

  Object.reverseMerge(I, {
    name: "McLovin",
    age: 25,
    homeState: "Hawaii"
  });

  var self = {
    introduce: function() {
      return "Hi I'm " + I.name + " and I'm " + I.age;
    }
  };

  // Including the Bindable module
  Object.extend(self, Bindable());

  return self;
}

var person = Person();
person.bind("eat", function() {
  alert(person.introduce() + " and I'm eating!");
});

person.trigger("eat"); // Blasts the alert!

곡개 : μ €λŠ” Daniel X. Moore {SUPER: SYSTEM}μž…λ‹ˆλ‹€. JavaScript둜 클래슀λ₯Ό μ •μ˜ν•˜λŠ” κ°€μž₯ 쒋은 λ°©λ²•μž…λ‹ˆλ‹€.


λ‹΅λ³€

var Animal = function(options) {
    var name = options.name;
    var animal = {};

    animal.getName = function() {
        return name;
    };

    var somePrivateMethod = function() {

    };

    return animal;
};

// usage
var cat = Animal({name: 'tiger'});

λ‹΅λ³€

λ‹€μŒμ€ μ§€κΈˆκΉŒμ§€ μ‚¬μš©ν•œ μžλ°” 슀크립트둜 객체λ₯Ό λ§Œλ“œλŠ” λ°©λ²•μž…λ‹ˆλ‹€.

예 1 :

obj = new Object();
obj.name = 'test';
obj.sayHello = function() {
    console.log('Hello '+ this.name);
}

예 2 :

obj = {};
obj.name = 'test';
obj.sayHello = function() {
    console.log('Hello '+ this.name);
}
obj.sayHello();

예 3 :

var obj = function(nameParam) {
    this.name = nameParam;
}
obj.prototype.sayHello = function() {
    console.log('Hello '+ this.name);
}

예제 4 : Object.create ()의 μ‹€μ œ 이점 [이 링크]λ₯Ό μ°Έμ‘°ν•˜μ‹­μ‹œμ˜€

var Obj = {
    init: function(nameParam) {
        this.name = nameParam;
    },
    sayHello: function() {
        console.log('Hello '+ this.name);
    }
};
var usrObj = Object.create(Obj);  // <== one level of inheritance

usrObj.init('Bob');
usrObj.sayHello();

예제 5 (μ‚¬μš©μž μ •μ˜ 된 Crockford의 Object.create) :

Object.build = function(o) {
   var initArgs = Array.prototype.slice.call(arguments,1)
   function F() {
      if((typeof o.init === 'function') && initArgs.length) {
         o.init.apply(this,initArgs)
      }
   }
   F.prototype = o
   return new F()
}
MY_GLOBAL = {i: 1, nextId: function(){return this.i++}}  // For example

var userB = {
    init: function(nameParam) {
        this.id = MY_GLOBAL.nextId();
        this.name = nameParam;
    },
    sayHello: function() {
        console.log('Hello '+ this.name);
    }
};
var bob = Object.build(userB, 'Bob');  // Different from your code
bob.sayHello();

ES6 / ES2015둜 닡변을 계속 μ—…λ°μ΄νŠΈν•˜λ €λ©΄

ν΄λž˜μŠ€λŠ” λ‹€μŒκ³Ό 같이 μ •μ˜λ©λ‹ˆλ‹€.

class Person {
    constructor(strName, numAge) {
        this.name = strName;
        this.age = numAge;
    }

    toString() {
        return '((Class::Person) named ' + this.name + ' & of age ' + this.age + ')';
    }
}

let objPerson = new Person("Bob",33);
console.log(objPerson.toString());

λ‹΅λ³€

JavaScriptμ—μ„œ Douglas Crockford의 Prototypal Inheritance와 JavaScript μ—μ„œ Classical Inheritanceλ₯Ό μ½μ–΄μ•Όν•œλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€ .

그의 νŽ˜μ΄μ§€μ—μ„œ 예 :

Function.prototype.method = function (name, func) {
    this.prototype[name] = func;
    return this;
};

효과? 보닀 μš°μ•„ν•œ λ°©λ²•μœΌλ‘œ λ©”μ†Œλ“œλ₯Ό μΆ”κ°€ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

function Parenizor(value) {
    this.setValue(value);
}

Parenizor.method('setValue', function (value) {
    this.value = value;
    return this;
});

λ˜ν•œ 그의 λΉ„λ””μ˜€λ₯Ό μΆ”μ²œν•©λ‹ˆλ‹€ :
Advanced JavaScript .

그의 νŽ˜μ΄μ§€μ—μ„œ 더 λ§Žμ€ λΉ„λ””μ˜€λ₯Ό 찾을 수 μžˆμŠ΅λ‹ˆλ‹€ : http://javascript.crockford.com/
John Reisig μ±…μ—μ„œ Douglas Crockfor의 μ›Ή μ‚¬μ΄νŠΈμ—μ„œ λ§Žμ€ 예제λ₯Ό 찾을 수 μžˆμŠ΅λ‹ˆλ‹€.