[javascript] 프로토 타입을 사용하는 경우 자바 스크립트

js에서 프로토 타입 메서드를 사용하는 것이 적절한시기를 이해하고 싶습니다. 항상 사용해야합니까? 아니면 사용이 선호되지 않거나 성능이 저하되는 경우가 있습니까?

이 사이트에서 js의 네임 스페이스를위한 일반적인 방법을 검색 할 때 대부분은 프로토 타입 기반이 아닌 구현을 사용하는 것으로 보입니다. 단순히 개체 또는 함수 개체를 사용하여 네임 스페이스를 캡슐화하는 것입니다.

클래스 기반 언어에서 왔기 때문에 병렬을 시도하고 그리지 않고 프로토 타입이 “클래스”와 같고 내가 언급 한 네임 스페이스 구현이 정적 메서드와 같다고 생각하는 것은 어렵습니다.



답변

프로토 타입은 최적화 입니다.

그것들을 잘 사용하는 좋은 예는 jQuery 라이브러리입니다. 를 사용하여 jQuery 객체를 얻을 때마다 $('.someClass')해당 객체에는 수십 개의 “메서드”가 있습니다. 라이브러리는 객체를 반환하여이를 달성 할 수 있습니다.

return {
   show: function() { ... },
   hide: function() { ... },
   css: function() { ... },
   animate: function() { ... },
   // etc...
};

그러나 이는 메모리의 모든 jQuery 객체가 동일한 메서드를 포함하는 수십 개의 명명 된 슬롯을 계속해서 가질 수 있음을 의미합니다.

대신 이러한 메서드는 프로토 타입에 정의되고 모든 jQuery 객체는 해당 프로토 타입을 “상속”하여 매우 적은 런타임 비용으로 모든 메서드를 얻습니다.

jQuery가 올바르게 작동하는 방법에서 가장 중요한 부분은 이것이 프로그래머에게 숨겨져 있다는 것입니다. 라이브러리를 사용할 때 걱정할 필요가없는 것이 아니라 순전히 최적화로 취급됩니다.

JavaScript의 문제는 네이 키드 생성자 함수가 호출자가 접두사를 기억해야 new한다는 점입니다. 그렇지 않으면 일반적으로 작동하지 않습니다. 이것에 대한 타당한 이유가 없습니다. jQuery는 평범한 함수 뒤에 그 말도 안되는 것을 숨겨서 올바르게 가져 오므로 $객체가 구현되는 방식에 신경 쓸 필요가 없습니다.

지정된 프로토 타입으로 객체를 편리하게 생성 할 수 있도록 ECMAScript 5에는 표준 기능이 포함되어 있습니다 Object.create. 크게 단순화 된 버전은 다음과 같습니다.

Object.create = function(prototype) {
    var Type = function () {};
    Type.prototype = prototype;
    return new Type();
};

생성자 함수를 작성한 다음 new.

언제 프로토 타입을 피하겠습니까?

유용한 비교는 Java 및 C #과 같은 인기있는 OO 언어와 비교하는 것입니다. 이들은 두 가지 종류의 상속을 지원합니다.

  • 인터페이스 당신 상속, 같은 클래스가 인터페이스의 모든 구성원에 대한 고유의 구현을 제공.implementinterface
  • 일부 메서드의 기본 구현을 제공 extend하는 구현 상속 class.

JavaScript에서 프로토 타입 상속은 구현 상속 의 일종입니다 . 따라서 (C # 또는 Java에서) 기본 동작을 얻기 위해 기본 클래스에서 파생 된 경우 재정의를 통해 약간 수정 한 다음 JavaScript에서 프로토 타입 상속이 의미가 있습니다.

그러나 C # 또는 Java에서 인터페이스를 사용한 상황이라면 JavaScript에서 특정 언어 기능이 필요하지 않습니다. 인터페이스를 나타내는 무언가를 명시 적으로 선언 할 필요가 없으며 해당 인터페이스를 “구현”하는 것으로 객체를 표시 할 필요가 없습니다.

var duck = {
    quack: function() { ... }
};

duck.quack(); // we're satisfied it's a duck!

즉, 객체의 각 “유형”에 “메서드”에 대한 고유 한 정의가있는 경우 프로토 타입에서 상속 할 가치가 없습니다. 그 후에는 각 유형에 할당하는 인스턴스 수에 따라 다릅니다. 그러나 많은 모듈 식 디자인에는 주어진 유형의 인스턴스가 하나뿐입니다.

사실, 많은 사람들은 구현 상속이 악하다고 제안했습니다 . 즉, 유형에 대한 몇 가지 일반적인 작업이있는 경우 기본 / 슈퍼 클래스에 넣지 않고 대신 개체를 전달하는 일부 모듈에서 일반 함수로 노출되는 것이 더 명확 할 수 있습니다. 당신은 그들이 작동하기를 원합니다.


답변

객체의 “비 정적”메서드를 선언하려면 프로토 타입을 사용해야합니다.

var myObject = function () {

};

myObject.prototype.getA = function (){
  alert("A");
};

myObject.getB = function (){
  alert("B");
};

myObject.getB();  // This works fine

myObject.getA();  // Error!

var myPrototypeCopy = new myObject();
myPrototypeCopy.getA();  // This works, too.


답변

내장 prototype객체 를 사용하는 한 가지 이유 는 공통 기능을 공유하는 객체를 여러 번 복제하려는 경우입니다. 프로토 타입에 메서드를 첨부하면 각 new인스턴스 마다 생성되는 메서드를 복제 할 필요가 없습니다 . 그러나에 메서드를 연결하면 prototype모든 인스턴스가 해당 메서드에 액세스 할 수 있습니다.

기본 Car()클래스 / 객체 가 있다고 가정 합니다.

function Car() {
    // do some car stuff
}

그런 다음 여러 Car()인스턴스 를 만듭니다 .

var volvo = new Car(),
    saab = new Car();

이제 각 자동차가 운전하고 켜야하는 등의 작업이 필요하다는 것을 알고 있습니다. 메서드를 Car()클래스에 직접 연결하는 대신 (생성 된 각 인스턴스 당 메모리를 차지함) 대신 프로토 타입에 메서드를 연결할 수 있습니다 (메소드 만 생성 한 번), 따라서 해당 메소드에 대한 액세스 권한을 new volvosaab.

// just mapping for less typing
Car.fn = Car.prototype;

Car.fn.drive = function () {
    console.log("they see me rollin'");
};
Car.fn.honk = function () {
    console.log("HONK!!!");
}

volvo.honk();
// => HONK!!!
saab.drive();
// => they see me rollin'


답변

특정 종류의 객체에 대한 많은 복사본을 만들고 모두 공통된 동작을 공유해야하는 경우 프로토 타입 객체에 함수를 배치합니다. 이렇게하면 각 함수의 복사본을 하나만 사용하여 메모리를 절약 할 수 있지만 이는 가장 간단한 이점 일뿐입니다.

프로토 타입 객체의 메서드를 변경하거나 메서드를 추가하면 해당 유형의 모든 인스턴스의 특성이 즉시 변경됩니다.

이제 이러한 모든 작업을 수행 하는 이유 는 대부분 자체 애플리케이션 디자인의 기능과 클라이언트 측 코드에서 수행해야하는 작업의 종류입니다. (완전히 다른 이야기는 서버 내부의 코드 일 것입니다. 거기에서 더 큰 규모의 “OO”코드를 수행하는 것을 상상하기 훨씬 쉽습니다.)


답변

클래스 기반 용어로 설명하면 Person은 클래스이고 walk ()는 Prototype 메서드입니다. 따라서 walk ()는 이것으로 새 객체를 인스턴스화 한 후에 만 ​​존재합니다.

따라서 Person u와 같은 개체의 복사본을 만들고 싶다면 많은 사용자를 만들 수 있습니다. Prototype은 메모리의 각 개체에 대해 동일한 함수 복사본을 공유 / 상속하여 메모리를 절약하므로 좋은 솔루션입니다.

정적은 그러한 시나리오에서 그다지 큰 도움이되지 않습니다.

function Person(){
this.name = "anonymous";
}

// its instance method and can access objects data data 
Person.prototype.walk = function(){
alert("person has started walking.");
}
// its like static method
Person.ProcessPerson = function(Person p){
alert("Persons name is = " + p.name);
}

var userOne = new Person();
var userTwo = new Person();

//Call instance methods
userOne.walk();

//Call static methods
Person.ProcessPerson(userTwo);

그래서 이것으로 더 비슷한 인스턴스 메소드입니다. 객체의 접근 방식은 정적 메서드와 같습니다.

https://developer.mozilla.org/en/Introduction_to_Object-Oriented_JavaScript


답변