객체 만들기 ---원형 모드와 구조 함수

8983 단어

객체 만들기


공장 모드

function createPerson(name, age, job){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function(){
        alert(this.name);
    };    
    return o;
}

var person1 = createPerson("Nicholas", 29, "Software Engineer");
var person2 = createPerson("Greg", 27, "Doctor");

person1.sayName();   //"Nicholas"
person2.sayName();   //"Greg"
  • 공장 모델은 여러 개의 비슷한 대상을 만드는 문제를 해결했지만 대상 식별 문제(즉 대상의 유형을 어떻게 아는지)를 해결하지 못했다

  • 구조 함수 모드

    function Person(name, age, job){
        this.name = name;
        this.age = age;
        this.job = job;
        this.sayName = function(){
            alert(this.name);
        };    
    }
    
    var person1 = new Person("Nicholas", 29, "Software Engineer");
    var person2 = new Person("Greg", 27, "Doctor");
    
    person1.sayName();   //"Nicholas"
    person2.sayName();   //"Greg"
    
    alert(person1 instanceof Object);  //true
    alert(person1 instanceof Person);  //true
    alert(person2 instanceof Object);  //true
    alert(person2 instanceof Person);  //true
    
    alert(person1.sayName == person2.sayName);  //false 
    
  • 구조 함수는 항상 대문자로 시작해야 한다. 새로운 실례를 만들려면 new 조작부호를 사용해야 한다
  • 모든 실례는constructor(구조 함수) 속성이 있는데 이 속성은 실례의 구조 함수를 가리킨다
      alert(person1.constructor == Person);  //true
      alert(person2.constructor == Person);  //true
    
  • 구조 함수와 다른 함수의 유일한 차이는 호출 방식이 다르다는 것이다. 모든 함수는 new 조작부호로 호출되면 구조 함수로 사용할 수 있다
  • 구조 함수의 문제: 모든 방법은 모든 실례에 대해 다시 한 번 만들어야 한다. 서로 다른 실례의 동명 방법은 사실 서로 같지 않다

  • 원형 모드

  • 모든 함수는prototype(원형) 속성이 있는데 이 속성은 하나의 지침으로 하나의 대상을 가리킨다. 이 대상의 역할은 특정 유형의 모든 실례가 공유할 수 있는 속성과 방법을 포함한다.프로토타입은 구조 함수를 호출하여 만든 그 대상의 실례적인 원형 대상입니다.
      function Person(){
      }
    
      Person.prototype.name = "Nicholas";
      Person.prototype.age = 29;
      Person.prototype.job = "Software Engineer";
      Person.prototype.sayName = function(){
          alert(this.name);
      };
      
      var person1 = new Person();
      person1.sayName();   //"Nicholas"
      
      var person2 = new Person();
      person2.sayName();   //"Nicholas"
      
      alert(person1.sayName == person2.sayName);  //true
    
  • 새로운 대상의 이러한 속성과 방법은 모든 실례가 공유하는 것이다

  • 원형 대상을 이해하다

  • 언제든지 새로운 함수를 만들면 특정한 규칙에 따라 이 함수에 프로토타입 속성을 생성합니다. 이 속성은 함수의 원형 대상을 가리킵니다
  • 기본적으로 모든 원형 대상은 자동으로constructor(구조 함수) 속성을 얻을 수 있습니다. 이 속성은prototype 속성이 있는 함수를 가리키는 바늘입니다.위의 예에서 말하자면, Person.prototype.constructor가 Person을 가리키는..
  • 사용자 정의 구조 함수를 만들면 그 원형 대상은constructor 속성만 얻을 수 있고 다른 방법은 모두 Object에서 계승된 것이다. 구조 함수를 호출하여 새로운 실례를 만들면 이 실례의 내부에는 구조 함수의 원형 대상을 가리키는 바늘(내부속성)이 포함된다.이 속성은 [[prototype]], 즉 프로토타입니다.주의: 이 연결은 실례와 구조 함수의 원형 대상 사이에 존재하며 구조 함수와 직접적인 관계가 없습니다
  • 모든 실현에서 [[prototype]]에 접근할 수 없지만 isPrototypeOf() 방법을 통해 대상 간에 이런 관계가 있는지 확인할 수 있습니다
      alert(Person.prototype.isPrototypeOf(person1));  //true
      alert(Person.prototype.isPrototypeOf(person2));  //true
    
  • Object.getPrototypeOf () 객체의 원형을 가져옵니다
      //only works if Object.getPrototypeOf() is available
      if (Object.getPrototypeOf){
          alert(Object.getPrototypeOf(person1) == Person.prototype);  //true
          alert(Object.getPrototypeOf(person1).name);  //"Nicholas"
      }
    
  • 원형은 처음에constructor 속성만 포함하고 이 속성도 공유되기 때문에 대상의 실례를 통해 접근할 수 있다
  • 객체 인스턴스를 통해 원형에 저장된 값에 액세스할 수 있지만 객체 인스턴스를 통해 원형의 값을 다시 쓸 수는 없습니다..
      function Person(){
      }
      
      Person.prototype.name = "Nicholas";
      Person.prototype.age = 29;
      Person.prototype.job = "Software Engineer";
      Person.prototype.sayName = function(){
          alert(this.name);
      };
      
      var person1 = new Person();
      var person2 = new Person();
      
      person1.name = "Greg";
      alert(person1.name);   //"Greg" from instance
      alert(person2.name);   //"Nicholas" from prototype
    
  • delete 조작부호를 통해 실례 속성을 완전히 삭제하여 원형의 속성에 다시 접근할 수 있습니다
      delete person1.name;
      alert(person1.name);   //"Nicholas" - from the prototype
    
  • hasOwnProperty() 방법은 하나의 속성이 실례에 존재하는지 원형에 존재하는지 측정할 수 있으며, 주어진 속성이 대상 실례에 있어야만 true로 되돌아갈 수 있다..

  • 원형과 in 조작부호

  • in 조작부호는 두 가지 사용 방식이 있는데 하나는 for-in 순환 중이고 하나는 단독으로 사용한다.단독으로 사용할 때, in 조작자는 대상을 통해 주어진 속성에 접근할 수 있을 때true를 되돌려줍니다. 이 속성이 실례에서든 원형에서든..
      function Person(){
      }
      
      Person.prototype.name = "Nicholas";
      Person.prototype.age = 29;
      Person.prototype.job = "Software Engineer";
      Person.prototype.sayName = function(){
          alert(this.name);
      };
      
      var person1 = new Person();
      var person2 = new Person();
      
      alert(person1.hasOwnProperty("name"));  //false
      alert("name" in person1);  //true
      
      person1.name = "Greg";
      alert(person1.name);   //"Greg" from instance
      alert(person1.hasOwnProperty("name"));  //true
      alert("name" in person1);  //true
      
      alert(person2.name);   //"Nicholas" from prototype
      alert(person2.hasOwnProperty("name"));  //false
      alert("name" in person2);  //true
      
      delete person1.name;
      alert(person1.name);   //"Nicholas" - from the prototype
      alert(person1.hasOwnProperty("name"));  //false
      alert("name" in person1);  //true
    
  • for-in 순환 시 대상을 통해 접근할 수 있는 모든 열거할 수 있는 속성을 되돌려줍니다
  • Object.keys () 는 하나의 대상을 매개 변수로 받아들여 모든 열거 가능한 속성을 포함하는 문자열 그룹을 되돌려줍니다
      function Person(){
      }
      
      Person.prototype.name = "Nicholas";
      Person.prototype.age = 29;
      Person.prototype.job = "Software Engineer";
      Person.prototype.sayName = function(){
          alert(this.name);
      };
      
      var keys = Object.keys(Person.prototype);
      alert(keys);   //"name,age,job,sayName"
    
  • Object.getownPropertyNames () 는 모든 인스턴스 속성을 얻을 수 있습니다
      var keys = Object.getOwnPropertyNames(Person.prototype);
      alert(keys);   //"constructor,name,age,job,sayName"
    

  • 더욱 간단한 원형 문법

    function Person(){
    }
    
    Person.prototype = {
        name : "Nicholas",
        age : 29,
        job: "Software Engineer",
        sayName : function () {
            alert(this.name);
        }
    };
    
  • Person을prototype 설정은 대상의 글씨체로 만든 새 대상과 같습니다.constructor는 더 이상 Person을 가리키지 않습니다.이렇게 본질적으로 기본적인prototype 대상을 완전히 다시 썼기 때문에constructor 속성도 새로운 대상의constructor 속성(Object) 구조 함수가 되어 Person 함수를 가리키지 않습니다..
      var friend = new Person();
      
      alert(friend instanceof Object);  //true
      alert(friend instanceof Person);  //true
      alert(friend.constructor == Person);  //false
      alert(friend.constructor == Object);  //true
    
  • constructor를 적당한 값으로 다시 설정할 수 있습니다..
      function Person(){
      }
      Person.prototype = {
      constructor: Person,
      name : "Nicholas",
      age : 29,
      job: "Software Engineer",
      sayName : function () {
          alert(this.name);
      }
      };
    
  • 이런 방식으로constructor 속성을 재설정하면 [[[Enumerable]] 특성이true로 설정됩니다.기본적으로 원생의constructor 속성은 일일이 다 들 수 없습니다..

  • 원형의 동적

  • 원형에서 찾을 가치가 있는 과정은 검색이기 때문에 원형 대상에 대한 우리의 모든 수정은 즉시 실례에서 반영될 수 있다. 설령 먼저 실례를 만든 후에 원형을 수정한다 하더라도..
  • 실례와 원형 간의 관계는 하나의 지침이지 사본이 아니다..
  • 구조 함수를 호출할 때 실례에 최초의 원형을 가리키는 [prototype]] 바늘을 추가합니다.전체 원형 대상을 다시 쓰면 구조 함수와 최초 원형 간의 관계를 끊는다.실례 중의 바늘은 원형만을 가리키며 구조 함수가 아니다!
      function Person(){
      }
      
      var friend = new Person();
              
      Person.prototype = {
          constructor: Person,
          name : "Nicholas",
          age : 29,
          job : "Software Engineer",
          sayName : function () {
              alert(this.name);
          }
      };
      
      friend.sayName();   //error
    
  • 위에서 잘못 보고한 원인은 원형 대상을 다시 써서 기존 원형과 이미 존재하는 대상 실례의 관계를 끊었기 때문이다.실례를 인용한 것은 여전히 원래의 원형이다

  • 조합 사용 구조 함수와 원형

  • 사용자 정의 유형을 만드는 가장 흔히 볼 수 있는 모델은 구조 함수와 원형을 조합하여 사용하는 것이다. 구조 함수는 실례 속성을 정의하는 데 사용되고 원형은 방법과 공유의 속성을 정의하는 데 사용된다.이렇게 하면 모든 실례는 자신의 실례 속성의 사본을 가지지만 방법에 대한 인용도 공유하여 메모리를 최대한 절약할 수 있다
      function Person(name, age, job){
          this.name = name;
          this.age = age;
          this.job = job;
          this.friends = ["Shelby", "Court"];
      }
      
      Person.prototype = {
          constructor: Person,
          sayName : function () {
              alert(this.name);
          }
      };
      
      var person1 = new Person("Nicholas", 29, "Software Engineer");
      var person2 = new Person("Greg", 27, "Doctor");
      
      person1.friends.push("Van");
      
      alert(person1.friends);    //"Shelby,Court,Van"
      alert(person2.friends);    //"Shelby,Court"
      alert(person1.friends === person2.friends);  //false
      alert(person1.sayName === person2.sayName);  //true
  • 좋은 웹페이지 즐겨찾기