>웹 프론트엔드 >JS 튜토리얼 >자바스크립트 프로토타입 상속_자바스크립트 기술의 작동원리와 예시에 대한 자세한 설명

자바스크립트 프로토타입 상속_자바스크립트 기술의 작동원리와 예시에 대한 자세한 설명

WBOY
WBOY원래의
2016-05-16 15:06:071518검색

먼저, 참고하실 수 있도록 JS 프로토타입 상속의 예시를 알려드리겠습니다

1. JS 프로토타입 상속

<!DOCTYPE html>
<html>

<head>
 <meta charset="UTF-8">
 <title>JS原型继承</title>
</head>

<body>
 <!--原型继承-->
 <script type="text/javascript">
 //clone()函数用来创建新的类Person对象
 var clone = function(obj) {
  var _f = function() {};
  //这句是原型式继承最核心的地方,函数的原型对象为对象字面量
  _f.prototype = obj;
  return new _f;
 }

 //先声明一个对象字面量
 var Animal = {
   somthing: 'apple',
   eat: function() {
    console.log("eat " + this.somthing);
   }
  }
  //不需要定义一个Person的子类,只要执行一次克隆即可
 var Cat = clone(Animal);
 //可以直接获得Person提供的默认值,也可以添加或者修改属性和方法
 console.log(Cat.eat());
 Cat.somthing = 'orange';
 console.log(Cat.eat());

 //声明子类,执行一次克隆即可
 var Someone = clone(Cat);
 </script>
</body>

</html>

2. JavaScript 프로토타입 상속 작동 방식

자바스크립트가 프로토타입 상속을 사용한다는 것은 잘 알려져 있지만 기본적으로 하나의 구현 인스턴스, 즉 new 연산자만 제공하기 때문에 이에 대한 설명은 항상 혼란스럽습니다. 다음으로 프로토타입 상속에 대한 설명과 정확히 어떻게 사용해야 할까요? 자바스크립트로요.

프로토타입 상속의 정의

JS 프로토타입 상속에 대한 설명을 읽다 보면 다음과 같은 텍스트를 자주 보게 됩니다.

객체의 속성을 찾을 때 JavaScript는 지정된 이름의 속성을 찾을 때까지 프로토타입 체인을 탐색합니다. ——JavaScript Secret Garden에서
대부분의 JavaScript 구현에서는 __proto__ 속성을 사용하여 객체의 프로토타입 체인을 나타냅니다. 이번 글에서는 __proto__와 프로토타입의 차이점이 무엇인지 살펴보겠습니다.

참고: __proto__는 코드에 표시되어서는 안되는 비공식적 사용법입니다. 여기서는 JavaScript 프로토타입 상속이 작동하는 방식을 설명하기 위해 사용됩니다.

다음 코드는 JS 엔진이 속성을 찾는 방법을 보여줍니다.

function getProperty(obj, prop) { 
 if (obj.hasOwnProperty(prop)) 
 return obj[prop] 
 
 else if (obj.__proto__ !== null) 
 return getProperty(obj.__proto__, prop) 
 
 else 
 return undefined 
} 

일반적인 예를 들어보겠습니다. 2차원 좌표가 x y 인 2차원 점에도 인쇄 방법이 있습니다.

앞서 언급한 프로토타입 상속의 정의를 사용하여 x, y 및 print라는 세 가지 속성을 가진 Point 개체를 만듭니다. 새로운 2차원 점을 생성하려면 새 객체를 생성하고 해당 객체의 __proto__ 속성이 Point를 가리키도록 해야 합니다.

var Point = { 
 x: 0, 
 y: 0, 
 print: function () { console.log(this.x, this.y); } 
}; 
 
var p = {x: 10, y: 20, __proto__: Point}; 
p.print(); // 10 20 

JavaScript의 이상한 프로토타입 상속

헷갈리는 점은 프로토타입 상속을 가르치는 모든 사람이 그런 코드를 제공하지 않고 다음 코드를 제공한다는 것입니다.

function Point(x, y) { 
 this.x = x; 
 this.y = y; 
} 
Point.prototype = { 
 print: function () { console.log(this.x, this.y); } 
}; 
 
var p = new Point(10, 20); 
p.print(); // 10 20 

이것은 약속한 것과 다릅니다. 여기서 Point는 함수가 되고, 프로토타입 속성이 있고, 새로운 연산자가 있습니다. 이 사람에게 무슨 일이 일어나고 있는 걸까요?

새 운영자의 작동 방식

창시자 Brendan Eich는 JS가 Java 및 C++와 같은 전통적인 객체 지향 프로그래밍 언어와 유사해지기를 원했습니다. 이러한 언어에서는 new 연산자를 사용하여 클래스에 대한 새 개체를 인스턴스화합니다. 그래서 그는 JS에 새로운 연산자를 작성했습니다.

C++에는 인스턴스 속성을 초기화하는 데 사용되는 생성자 개념이 있으므로 new 연산자는 함수를 대상으로 해야 합니다.
객체의 메소드를 한 곳에 모아야 하는데, 프로토타입 언어를 사용하고 있기 때문에 함수의 프로토타입 속성에 넣습니다.
new 연산자는 함수 F와 해당 인수인 new F(인수...)를 허용합니다. 이 프로세스는 세 단계로 구분됩니다.

클래스의 인스턴스를 만듭니다. 이번 단계는 빈 객체의 __proto__ 속성을 F.prototype으로 설정하는 것입니다.
인스턴스를 초기화합니다. 함수 F는 전달된 인수와 함께 호출되며 키워드 this는 인스턴스로 설정됩니다.
인스턴스를 반환합니다.
이제 new가 어떻게 작동하는지 알았으니 JS 코드로 구현할 수 있습니다.

function New (f) { 
 var n = { '__proto__': f.prototype }; /*第一步*/ 
 return function () { 
 f.apply(n, arguments);  /*第二步*/ 
 return n;    /*第三步*/ 
 }; 
} 

그의 근무 현황을 살펴보는 작은 예:

function Point(x, y) { 
 this.x = x; 
 this.y = y; 
} 
Point.prototype = { 
 print: function () { console.log(this.x, this.y); } 
}; 
 
var p1 = new Point(10, 20); 
p1.print(); // 10 20 
console.log(p1 instanceof Point); // true 
 
var p2 = New (Point)(10, 20); 
p2.print(); // 10 20 
console.log(p2 instanceof Point); // true 

JavaScript의 진정한 프로토타입 상속

JS의 ECMA 사양에서는 프로토타입 상속에만 new 연산자를 사용할 수 있습니다. 그러나 위대한 거장 Douglas Crockford는 진정한 프로토타입 상속을 달성하기 위해 new를 사용하는 방법을 발견했습니다! 그는 Object.create 함수를 다음과 같이 작성했습니다.

Object.create = function (parent) { 
 function F() {} 
 F.prototype = parent; 
 return new F(); 
}; 

이상해 보이지만 매우 깔끔합니다. 새 객체를 생성하고 해당 프로토타입을 원하는 값으로 설정합니다. __proto__ 사용을 허용하면 다음과 같이 작성할 수도 있습니다.

Object.create = function (parent) { 
 return { '__proto__': parent }; 
}; 

다음 코드를 사용하면 포인트가 진정한 프로토타입 상속을 채택할 수 있습니다.

var Point = { 
 x: 0, 
 y: 0, 
 print: function () { console.log(this.x, this.y); } 
}; 
 
var p = Object.create(Point); 
p.x = 10; 
p.y = 20; 
p.print(); // 10 20 

결론

JS 프로토타입 상속이 무엇인지, JS가 이를 특정 방식으로 구현하는 방법을 배웠습니다. 그러나 실제 프로토타입 상속(예: Object.create 및 __proto__)을 사용하면 여전히 다음과 같은 단점이 있습니다.

잘못된 표준화: __proto__는 표준 사용법이 아니거나 더 이상 사용되지 않는 사용법입니다. 동시에 원본 Object.create와 Dao Ye가 작성한 원본 버전도 다릅니다.
최적화 불량: 기본 Object.create이든 사용자 정의된 Object.create이든 성능은 새 것보다 훨씬 덜 최적화되며 전자는 후자보다 최대 10배 느립니다.

위 내용은 이 글의 전체 내용입니다. 모든 분들의 공부에 도움이 되었으면 좋겠습니다.

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