>웹 프론트엔드 >JS 튜토리얼 >자바스크립트 디자인 패턴(상속)_javascript 기술 배우기

자바스크립트 디자인 패턴(상속)_javascript 기술 배우기

WBOY
WBOY원래의
2016-05-16 15:29:391051검색

1. 상속

JavaScript의 상속은 다른 객체 지향 언어의 상속보다 훨씬 더 복잡한 매우 복잡한 주제입니다. 대부분의 다른 객체 지향 언어에서는 클래스에서 상속하려면 키워드만 사용해야 합니다. 이들과 달리 자바스크립트에서는 공개 멤버 상속이라는 목적을 달성하기 위해서는 일련의 조치가 필요하다. 게다가 JavaScript는 프로토타입 상속을 사용하는 몇 안 되는 언어 중 하나입니다. 언어의 유연성 덕분에 표준 클래스 기반 상속이나 보다 미묘한 프로토타입 상속을 사용할 수 있습니다.

2. 상속이 필요한 이유는 무엇인가요?

일반적으로 클래스를 디자인할 때 우리는 반복적인 코드를 줄이고 객체 간의 결합을 약화시키려고 노력합니다. 상속을 사용하면 이전 디자인 원칙의 요구 사항을 충족합니다. 이 메커니즘을 사용하면 기존 클래스를 기반으로 디자인하고 이미 가지고 있는 메서드를 활용할 수 있으며 디자인을 수정하기가 더 쉽습니다. 특정 방식으로 클래스 구조를 출력하는 toString() 메서드를 갖기 위해 여러 클래스가 필요하다고 가정해 보겠습니다. 물론 toString() 메서드를 정의하는 코드를 각 클래스에 복사하여 붙여 넣을 수도 있지만 이렇게 하면 언제든지 이 방법이 작동하는 방식을 변경해야 하며 모든 수업에서 동일한 수정을 반복해야 합니다. 반면에 ToStringProvider 클래스를 제공하고 해당 클래스가 이 클래스를 상속하도록 하는 경우 toString 메서드는 한 위치에서만 선언하면 됩니다.

한 클래스가 다른 클래스에서 상속받게 되면 둘 사이에 강한 결합이 발생할 수 있습니다. 즉, 한 클래스가 다른 클래스의 내부 구현에 종속됩니다. 다른 클래스에 메소드를 제공하기 위해 도펀트 클래스를 사용하는 것을 포함하여 이 문제를 방지하는 데 도움이 될 수 있는 몇 가지 기술에 대해 논의하겠습니다.

3. 클래스 기반 상속

아래 코드를 보세요:

<script type="text/javascript"> 


  function Person(name, age) 
  { 
   this.name = name; 
   this.age = age; 
  } 
  Person.prototype.say = function () 
  { 
   console.log(this.name + " , " + this.age); 
  } 
  function Student(no) 
  { 
   this.no = no; 
  } 
  /** 
   * Student的prototype指向Person的对象 
   */</span> 
  Student.prototype = new Person(); 
  var stu1 = new Student("0001"); 
  stu1.name = '张三'; 
  stu1.age = '11'; 
  console.log(stu1.no); 
  stu1.say(); 
 </script> 

출력 결과:
장산, 11세
Student가 Person을 성공적으로 통합했으며 Person의 say 메소드를 가지고 있음을 볼 수 있습니다. 핵심 코드는 실제로 Student.prototype = new Person();입니다.

Student.prototype이 new Person()을 가리키고, 새로운 Person의 _proto_가 Person Prototype을 가리키면 전체 상속이 완료됩니다.

그러나 이 접근 방식에는 문제가 있습니다.

문제 1: 상위 클래스에 참조 유형 변수가 있는 경우 데이터가 일치하지 않습니다. 다음으로 유형이 배열인 Person에 취미 속성을 추가합니다.

<script type="text/javascript"> 
  /** 
  * 存在问题 
  * 1、无法在Student的构造方法中传递参数用于父类的构造方法 
  * 2、对于引用类型变量,造成数据不一致 
  */ 


  function Person(name, age) 
  { 
   this.name = name; 
   this.age = age; 
   this.hobbies = [] ; 
  } 
  Person.prototype.say = function () 
  { 
   console.log(this.name + " , " + this.age +" , " +this.hobbies); 
  } 
  function Student(no) 
  { 
   this.no = no; 
  } 
  Student.prototype = new Person(); 

  var stu1 = new Student("0001"); 
  stu1.name = '张三'; 
  stu1.age = '11'; 
  stu1.hobbies.push("soccer"); 
  stu1.say(); 

  var stu2 = new Student("0002"); 
  stu2.name = '李四'; 
  stu2.age = '12'; 
  stu2.hobbies.push("girl"); 
  stu2.say(); 
 </script> 

출력 결과:
장산, 11세, 축구
Li Si , 12세, 축구, 소녀
John Doe의 취미는 소녀여야 한다는 것을 알 수 있지만, 위 코드에서는 모든 객체가 취미 속성을 공유하도록 허용합니다.
위의 상속 방법에는 여전히 문제가 있습니다.

질문 2: Student 생성자에서 new Student("00001", "Zhang San", 12)를 사용하여 객체를 생성하고 이름을 초기화할 수 없습니다. age 속성에는 stu.name, stu.age

를 할당해야 합니다.

위 문제를 해결하려면 위 코드를 수정하세요.

<script type="text/javascript"> 

  function Person(name, age) 
  { 
   this.name = name; 
   this.age = age; 
   this.hobbies = []; 
  } 
  Person.prototype.say = function () 
  { 
   console.log(this.name + " , " + this.age +" , " + this.hobbies); 
  } 

  function Student(name, age, no) 
  { 
   /** 
   * 使用call方法,第一个参数为上下文; 
   * 有点类似Java中的super(name,age)的感觉 
   */ 
   Person.call(this, name, age); 
   this.no = no; 
  } 

  Student.prototype = new Person(); 

  var stu1 = new Student("0001","张三",11); 
  stu1.hobbies.push("soccer"); 
  stu1.say(); 

  var stu2 = new Student("0002","李四",12); 
  stu2.hobbies.push("cangjin"); 
  stu2.hobbies.push("basketball"); 
  stu2.say(); 
 </script> 

출력:
0001, 장산, 축구
0002, 리시, 창진, 농구
학생 생성자에서 Person.call(this,name,age)을 사용하면 super(name,age) [호출의 첫 번째 매개변수는 컨텍스트임]처럼 느껴지고 속성 공유 문제를 성공적으로 해결합니다. 완벽하게 해결되었습니다.

4. 프로토타입 체인 기반 상속

<script type="text/javascript"> 

 /** 
  * 基于原型链的集成中都是对象 
  * 存在问题: 
  * 1、对于引用类型变量,造成数据不一致 
  */ 
 var Person = { 
    name: "人", 
    age: 0, 
    hobbies: [], 
    say: function () 
    { 
     console.log(this.name + " , " + this.age + " , " + this.hobbies); 
    } 
   } 
   ; 

 var Student = clone(Person); 
 Student.no =""; 
 Student.sayHello = function() 
 { 
  console.log(this.name +"hello ") ; 
 } 

 var stu1 = clone(Student); 
 stu1.name = "zhangsan"; 
 stu1.age = 12; 
 stu1.hobbies.push("Java"); 
 stu1.say(); 

 var stu2 = clone(Student); 
 stu2.name = "lisi"; 
 stu2.age = 13; 
 stu2.hobbies.push("Javascript"); 
 stu2.say(); 

 /** 
  * 返回一个prototype执行obj的一个对象 
  * @param obj 
  * @returns {F} 
  */ 
 function clone(obj) 
 { 
  var F = function () 
  { 
  }; 
  F.prototype = obj; 
  return new F(); 

 } 
</script> 

출력:
장산, 12, 자바
lisi, 13, Java,Javascript
참조 속성이 일관되지 않는 문제도 있음을 알 수 있으며, 전체 동작이 객체 기반이므로 사람들에게 좋은 느낌을 주지 않습니다. 그 원리는 아래 다이어그램을 통해 설명됩니다.

객체는 복제 함수를 통해 지속적으로 새로운 객체를 반환하고, 프로토타입은 들어오는 객체를 실행합니다. 실제로 전체 상속 과정은 _proto_ 지속적으로 가리키며 체인을 형성하므로 이를 프로토타입 체인이라고 합니다.

자, js의 두 가지 통합 방법 중 가장 좋은 방법은 비교적 안정적인 클래스 상속을 이용하는 것입니다.

위는 상속에 관한 관련 지식 포인트를 소개한 내용이므로 모든 분들의 학습에 도움이 되기를 바랍니다.

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.