>웹 프론트엔드 >JS 튜토리얼 >JavaScript의 어려움: 프로토타입 및 생성자 바인딩 예제에 대한 자세한 설명

JavaScript의 어려움: 프로토타입 및 생성자 바인딩 예제에 대한 자세한 설명

伊谢尔伦
伊谢尔伦원래의
2017-07-20 15:37:561574검색

JavaScript 개체 및 생성자

JavaScript 개체 정의는 다음과 같이 정의할 수 있습니다


var a = {
	x : 1,
	y : 2,
	add : function () {
		return this.x + this.y;
	},
	mul : function () {
		return this.x * this.y;
	}
}

이런 방식으로 두 개의 공개 멤버 x와 y 외에도 이 변수에는 다음이 포함됩니다. 두 개의 add 및 mul 함수(공용 메소드). 그러나 이 정의 방법에는 두 가지 단점이 있습니다.

1. 객체를 일괄적으로 생성하는 것은 매우 불편합니다. var b=a; 그러면 b의 멤버를 수정할 때마다 a의 멤버도 변경됩니다. 메커니즘 때문입니다

2. 객체를 생성할 때마다 일부 멤버를 사용자 정의해야 하는 경우 해당 할당 작업을 작성하고 코드 줄 수를 늘려야 합니다.

따라서 JavaScript 객체를 정의하기 전에 먼저 생성자를 정의할 수 있습니다.


function A(x, y) {
	this.x = x;
	this.y = y;
	this.add = function () {
		return this.x + this.y;
	}
	this.mul = function () {
		return this.x * this.y;
	}
}

그런 다음 객체를 정의합니다


a = new A(1, 2);

위 코드는 간단해 보이지만 C++와 같은 객체지향 언어와는 구별되어야 합니다. A는 "클래스"라는 개념이 아닙니다. "엄격한 의미에서. JavaScript에는 클래스가 없기 때문에 생성자만 호출합니다.

이제 질문이 생깁니다. 상속을 어떻게 구현합니까? C++는 캡슐화, 상속, 다형성이라는 세 가지 객체 지향 기능을 명확하게 구현합니다. 그러나 JavaScript와 같은 상대적으로 거친 언어의 경우 엄격한 상속 메커니즘이 없으며 대신 다음 방법을 사용하여 시뮬레이션합니다.

JavaScript 프로토타입

적용이나 호출 기능에 대해서는 나중에 설명하기 위해 여기서는 프로토타입을 먼저 소개합니다. 프로토타입은 Function에만 사용 가능합니다.

상속을 잘 사용하려면 먼저 상속이 왜 설계되었는지 이해해야 겠죠? 코드 재사용을 위해서는 "공통 부분 추출"에 지나지 않습니다.

그래서 JavaScript에서는 공개 부분도 Function의 프로토타입에 배치됩니다.

상속을 구현하기 위해 프로토타입을 사용하는 두 가지 예를 비교해 보겠습니다.


function A(x, y) {
	this.x = x;
	this.y = y;
	this.add = function () {
		return this.x + this.y;
	}
	this.mul = function () {
		return this.x * this.y;
	}
}

function B(x,y){
	
}

B.prototype=new A(1,2);

console.log(new B(3,4).add());  //3

이 예에서 하위 클래스의 프로토타입은 클래스 A 객체를 가리킵니다.

B가 A를 상속하는 또 다른 예를 구현해 보겠습니다.


function A() {
	
}

A.prototype = {
	x : 1,
	y : 2,
	add : function () {
		return this.x + this.y;
	},
	mul : function () {
		return this.x * this.y;
	}
}
A.prototype.constructor=A;

function B(){
	
}

B.prototype=A.prototype;
B.prototype.constructor=B;

B의 프로토타입 객체는 A의 프로토타입 객체를 참조하므로 B의 프로토타입 객체가 수정되면 A의 프로토타입 객체도 수정됩니다. 왜냐하면 본질적으로 모두 메모리 조각을 가리키기 때문입니다. 따라서 B 유형의 프로토타입을 변경할 때마다 혼동을 방지하기 위해 생성자를 수동으로 다시 변경해야 합니다. 두 예제와 비교하면 이전 예제에서는 참조가 없기 때문에 이 문제가 발생하지 않습니다.

B 유형의 객체 생성


b=new B();

b 객체에는 A 유형의 모든 멤버가 있습니다


console.log(b.add());  //3

모든 프로토타입 객체에는 생성자와 _proto_라는 두 가지 중요한 멤버가 있기 때문에 생성자는 기본적으로 함수 포인터입니다. 따라서 B.prototype=A.prototype이 실행된 후에는 생성자를 덮어쓰므로 나중에 생성자를 B 유형의 생성자로 리디렉션해야 합니다.

JavaScript 생성자 바인딩

A 유형의 생성자를 정의한 후 B 유형을 정의한 다음 B 유형 생성자 내부에 A 유형 생성자를 "실행"합니다.


function A(x, y) {
	this.x = x;
	this.y = y;
	this.add = function () {
		return this.x + this.y;
	}
	this.mul = function () {
		return this.x * this.y;
	}
}

function B(x, y, z) {
	A.apply(this, arguments);
	this.z = z;
}

console.log(new B(1,2,3));

적용함수는 호출함수와 기본적으로 동일하며, B형 생성자 내부에서 A형 생성자를 실행할 수 있습니다. 동시에 A의 모든 구성원을 상속받을 수도 있습니다.

결과 표시:

공식은 다음과 같습니다. B 생성자에 A.apply(this)를 작성하면 B가 생성한 객체가 A 생성자의 모든 멤버를 가질 수 있습니다.

신청하고 호출하면 다중상속도 가능해요


function IA(){
	this.walk=function(){
		console.log("walk");
	}
}

function IB(){
	this.run=function(){
		console.log("run");
	}
}

function Person(){
	IA.apply(this);
	IB.apply(this);
}

var p=new Person();
p.walk();  //walk    
p.run();  //run

위 내용은 JavaScript의 어려움: 프로토타입 및 생성자 바인딩 예제에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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