>  기사  >  웹 프론트엔드  >  JavaScript 객체 지향 - 프로토타입 재작성

JavaScript 객체 지향 - 프로토타입 재작성

黄舟
黄舟원래의
2017-01-19 15:14:501602검색

지난 글에서는 프로토타입의 메모리 모델을 소개하고, 4장의 사진을 통해 각 단계별 프로토타입의 상태를 분석해보았습니다. 아래에서는 먼저 일반적으로 사용되는 프로토타입 및 객체 속성 감지 방법을 소개합니다. 이전 기사의 Person 클래스를 예로 들어 보겠습니다. Person 클래스를 생성하는 코드는 다음과 같습니다.

function Person(){};
 
Person.prototype.name = "Leon";
Person.prototype.age = 22;
Person.prototype.say = fucntion(){
  alert(this.name + "," + this.age);
}
 
var p1 = new Person();
var p2 = new Person();
p2.name = "Ada";
 
p1.say();
p2.say();

1. 객체가 함수

alert(Person.prototype.isPrototypeOf(p1));    //true

의 프로토타입인지 감지합니다. 이 방법은 p1의 프로토타입이 Person인지 여부를 감지할 수 있습니다.

2. 객체 생성자 감지

alert(p1.constructor == Person);    //true

3. 속성이 자신의 속성인지 감지

alert(p1.hasOwnProperty("name"));   //false
alert(p2.hasOwnProperty("name"));   //true

객체 p1에는 자체 공간에 이름 속성이 없습니다. . 그래서 false를 반환합니다. 객체 p2는 name 속성을 다시 할당하고 name 속성이 해당 공간에 존재하므로 true를 반환합니다.

4. delete를 통해 자체 공간의 속성 삭제

delete p2.name;
p2.say();
alert(p2.hasOwnProperty("name")); //false

위 코드와 같이 delete를 사용하여 객체의 자체 공간에 있는 속성을 삭제할 수 있습니다.

5. in 속성을 사용하여 객체가 프로토타입이나 자체에 특정 속성을 포함하는지 감지합니다.

alert("name" in p1); //在原型中有,所以为true
alert("name" in p2); //在自己的空间中有,所以为true

프로토타입이나 자체 공간에 속성이 없으면 결과를 얻습니다. 그것은 거짓이다.

6. 프로토타입에 특정 속성이 존재하는지 감지하는 사용자 정의 메소드

function hasPrototypeProperty(obj,prop){
  return(!obj.hasOwnProperty(prop) && (prop in obj));
}

위 코드에서는 프로토타입에 특정 속성이 존재하는지 감지하는 메소드를 사용자 정의했습니다. 이 메소드는

alert(hasPrototypeProperty(p1,"name")); //true
alert(hasPrototypeProperty(p2,"name")); //false

p1 객체의 name 속성이 프로토타입에 존재하므로 true를 반환하고, p2 객체의 name 속성은 자체 공간에 있으므로 false를 반환합니다.

프로토타입 다시 작성

이전처럼 코드를 작성하면 Person.prototype.xxx 문이 많아 읽고 이해하기가 쉽지 않습니다. Json과 같은 형식으로 프로토타입을 다시 작성할 수 있습니다. 코드는 다음과 같습니다.

//重写原型
Person.prototype = {
  name:"Leon",
  age:22,
  say:function(){
    alert(this.name+ "," + this.age);
  }
}
var p1 = new Person();
p1.say();

위의 방법을 사용하여 프로토타입을 다시 작성한 후 프로토타입이 다시 작성되었으며 Person.prototype을 통해 지정되지 않았습니다. 이번에는 생성자가 더 이상 Person을 가리키지 않고 Object를 가리킵니다.

alert(p1.constructor == Person); //false

생성자가 프로그램에 정말 중요한 경우 json에서 프로토타입 포인터를 선언할 수 있습니다.

Person.prototype = {
  constructor:Person, //手动指定constructor
  name:"Leon",
  age:22,
  say:function(){
    alert(this.name+ "," + this.age);
  }
}

프로토타입 재작성 문제

프로토타입을 재작성할 때 다음과 같은 문제가 발생할 수 있습니다. 다음으로, 먼저 문제를 일으킬 수 있는 재작성된 프로토타입 코드 조각을 살펴보고 코드의 각 단계에서 메모리 모델을 분석해 보겠습니다. 코드는 다음과 같습니다.

// 创建Person类
function Person(){}
 
var p1 = new Person();
//在Person的原型上添加了sayHi()方法
Person.prototype.sayHi = function(){
  alert(this.name + "Hi!");
}
p1.sayHi();   //输出: undefined:hi!
 
// 对Person原型进行重写
Person.prototype = {
  constructor:Person, //手动指定constructor
  name:"Leon",
  age:22,
  say:function(){
    alert(this.name+ "," + this.age);
  }
}
 
var p2 = new Person();
p2.sayHi();
 
p2.say();//正确
p1.say();//报错

위 코드에서는 먼저 Person 클래스를 생성합니다. 이때 Person 프로토타입의 메모리 모델은 아래와 같습니다.

JavaScript 객체 지향 - 프로토타입 재작성

그런 다음 p1 객체를 생성하고 Person 프로토타입에 sayHi() 메서드를 추가했습니다. 이때 Person 프로토타입의 메모리 모델은 아래와 같습니다.

var p1 = new Person();
//在Person的原型上添加了sayHi()方法
Person.prototype.sayHi = function(){
  alert(this.name + "Hi!");
}
p1.sayHi();   //输出: undefined:hi!

JavaScript 객체 지향 - 프로토타입 재작성


현재 메모리 모델에 주목하세요. 이 상태에서는 p1 객체 자신의 공간이나 Person 프로토타입에 name 속성이 없기 때문에 p1.sayHi() 메서드가 실행되면 this.name 속성이 정의되지 않고 최종 출력 결과는 undefine:hi 가 됩니다. !.

다음으로 Person 프로토타입을 다시 작성하고 프로토타입에 몇 가지 속성과 메서드를 추가했습니다.

// 对Person原型进行重写
Person.prototype = {
  constructor:Person //手动指定constructor
  name:"Leon",
  age:22,
  say:function(){
    alert(this.name+ "," + this.age);
  }
}
p1.sayHi();   //输出: undefined:hi!

이번 프로토타입 메모리 모델은 아래와 같습니다.

JavaScript 객체 지향 - 프로토타입 재작성

프로토타입이 다시 작성된 후 JavaScript는 프로토타입에 새로운 메모리를 할당하고, Person 클래스는 새 프로토타입 객체를 가리키며 원래 생성된 p1 객체의 _proto_ 속성은 여전히 ​​이전 프로토타입 객체를 가리킵니다.

이때 p1.sayHi()를 실행하면 프로그램은 오류를 보고하지 않지만 실행 결과는 여전히 undefine:hi!입니다. p1 객체에 name 속성이 없고 프로토타입은 .

마지막으로 프로토타입 재작성 후 객체 p2를 생성합니다.

var p2 = new Person();
p2.sayHi();

이번 프로토타입 메모리 모델은 아래와 같습니다.

JavaScript 객체 지향 - 프로토타입 재작성

새로 생성된 p2 객체의 _proto_ 속성은 다시 작성된 Prototype 객체를 가리키며, 이때 p2.sayHi() 메소드가 실행되면 p2 객체와 그것이 가리키는 프로토타입에는 sayHi() 메소드가 없으므로 프로그램은 오류를 보고하게 됩니다.

이때 p1.say() 메소드를 실행하면 p1이나 그것이 가리키는 프로토타입에 say() 메소드가 없기 때문에 프로그램에서 오류를 보고하게 됩니다.

위의 프로토타입 메모리 모델 분석을 통해 프로토타입 재작성 위치가 객체의 속성과 메서드에 직접적인 영향을 미친다는 것을 알 수 있습니다. 다시 쓰기 전에 생성된 객체와 다시 쓰기 후에 생성된 객체의 속성과 메서드가 다릅니다. . 같은. 위의 메모리 모델 다이어그램을 항상 염두에 두어야 합니다.

위 내용은 JavaScript 객체지향 프로토타입 재작성 내용입니다. 더 많은 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!


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