웹 프론트엔드 JS 튜토리얼 JavaScript 시리즈에 대한 심층적 이해 (6) 강력한 프로토타입 및 프로토타입 chain_javascript 기술

JavaScript 시리즈에 대한 심층적 이해 (6) 강력한 프로토타입 및 프로토타입 chain_javascript 기술

May 16, 2016 pm 05:57 PM
원기 프로토타입 체인

서문
JavaScript는 전통적인 클래스 상속 모델을 포함하지 않고 프로토타입 프로토타입 모델을 사용합니다.

이것이 JavaScript의 단점으로 자주 언급되지만 실제로는 프로토타입 기반 상속 모델이 기존 클래스 상속보다 더 강력합니다. 전통적인 클래스 상속 모델을 구현하는 것은 쉽지만 JavaScript에서 프로토타입 상속을 구현하는 것은 훨씬 더 어렵습니다.

자바스크립트는 프로토타입 상속을 기반으로 널리 사용되는 유일한 언어이므로 두 상속 모델의 차이점을 이해하는 데는 시간이 좀 걸립니다. 오늘은 프로토타입과 프로토타입 체인에 대해 알아 보겠습니다.

프로토타입
10년 전 처음 JavaScript를 배울 때 저는 주로 다음과 같은 방식으로 코드를 작성했습니다.

코드 복사 코드는 다음과 같습니다:

vardecimalDigits = 2,
tax = 5

function add(x, y) {
return x y
}

function subtract(x, y) {
return x - y
}

//alert(add(1, 3));

각 함수를 실행하여 결과를 얻으면, 프로토타입을 학습한 후 다음과 같은 방법을 사용하여 코드를 아름답게 만들 수 있습니다.

프로토타입 사용 방법 1:
프로토타입을 사용하기 전에 코드를 약간 수정해야 합니다.
코드 복사 코드는 다음과 같습니다.

var Calculator = function (decimalDigits, Tax) {
this.decimalDigits =decimalDigits;
this.tax = Tax; >};

그런 다음 Calculator 객체의 프로토타입 속성에 객체 리터럴을 할당하여 Calculator 객체의 프로토타입을 설정합니다.

코드 복사 코드는 다음과 같습니다.
Calculator.prototype = {
add : 함수 ( x, y) {
return x y;
},

빼기: 함수 (x, y) {
return x - y; ;
//alert((new Calculator()).add(1, 3));


이런 방식으로 새 Calculator 객체 다음에 add 메서드를 호출하여 결과를 계산할 수 있습니다. .
프로토타입 사용법 2:
두 번째 방법은 프로토타입 프로토타입을 할당할 때 함수가 즉시 실행되는 표현식을 사용하는 것인데, 형식은 다음과 같습니다.

Calculator.prototype = function () { } ();
장점은 이전 게시물에서 이미 알려져 있습니다. 즉, 비공개 함수를 캡슐화하고 간단한 사용 이름을 반환 형식으로 노출하여 공개/비공개 효과를 얻을 수 있다는 것입니다.



코드 복사 코드는 다음과 같습니다. Calculator.prototype = function () {
추가 = 함수(x, y) {
x y 반환
},

빼기 = 함수(x, y) {
x - y 반환; 🎜> }
return {
더하기: 더하기,
빼기: 빼기
}
} ()

//alert((new Calculator()).add (11 , 3));


같은 방식으로 새 Calculator 개체를 만들고 나중에 add 메서드를 호출하여 결과를 계산할 수 있습니다.

한 가지 더
단계별 설명:
위의 프로토타입을 사용할 때 프로토타입 개체를 한 번에 설정하는 데 한계가 있습니다. 프로토타입은 별도로.




코드 복사
코드는 다음과 같습니다. var BaseCalculator = function () { // 각 인스턴스에 대해 10진수 선언
this.decimalDigits = 2;
};

//프로토타입을 사용하여 BaseCalculator에 대한 2개의 객체 메서드 확장
BaseCalculator.prototype.add = 함수(x, y) {
return x y;
};

BaseCalculator.prototype.subtract = 함수(x, y) {
return x - y; ;


먼저 생성자에서 BaseCalculator 객체를 선언합니다. 십진수 속성인decimalDigits가 초기화되고 프로토타입 속성을 통해 add(x,y)와 뺄셈이라는 두 함수가 설정됩니다. (x, y) 물론 위에서 언급한 두 가지 방법 중 하나를 사용할 수도 있습니다. 우리의 주요 목적은 BaseCalculator 개체를 실제 계산기의 프로토타입으로 설정하는 방법을 확인하는 것입니다.



코드 복사
코드는 다음과 같습니다. var BaseCalculator = function() { this.decimalDigits = 2; };
BaseCalculator.prototype = {
add: function(x, y) {
return x y; : 함수( x, y) {
return x - y
}
};
위 코드를 생성한 후 시작해 보겠습니다.
코드 복사 코드는 다음과 같습니다.

var Calculator = function () {
//각 인스턴스에 대한 세금 번호 선언
this.tax = 5
}

Calculator.prototype = new BaseCalculator( ) ;

Calculator가 두 가지 기능인 add(x,y)와 subtract(x,y)를 통합할 수 있도록 Calculator의 프로토타입이 BaseCalculator의 인스턴스를 가리키는 것을 볼 수 있습니다. , 그리고 한 가지 더 말해야 할 점은 프로토타입이 BaseCalculator의 인스턴스이기 때문에 얼마나 많은 Calculator 객체 인스턴스를 생성하더라도 해당 프로토타입은 동일한 인스턴스를 가리킨다는 것입니다.
코드 복사 코드는 다음과 같습니다.

var calc = new Calculator()
alert(calc.add(1, 1));
//BaseCalculator에 선언된 maximumDigits 속성은 계산기
alert(calc.decimalDigits)

에서 액세스할 수 있습니다. 위 코드를 실행하면 Calculator의 프로토타입이 BaseCalculator의 인스턴스를 가리키기 때문에 Calculator가 BaseCalculator의 생성자에 선언된 속성 값에 액세스하는 것을 원하지 않는 경우에는 해당 DecimalDigits 속성 값에 액세스할 수 있음을 알 수 있습니다. 할? 이렇게 하세요:
코드를 복사하세요 코드는 다음과 같습니다:

var Calculator = function ( ) {
this.tax= 5;
};

Calculator.prototype = BaseCalculator.prototype;

Calculator의 프로토타입에 할당 , 계산기에 있으므로 인스턴스에서 소수점 값에 액세스할 수 없습니다. 다음 코드에 액세스하면 오류가 발생합니다.
코드 복사 코드는 다음과 같습니다.

var calc = new Calculator()
alert (calc.add(1, 1));
alert(calc.decimalDigits);

프로토타입 다시 작성:
타사 JS 라이브러리를 사용할 때 그들이 정의한 프로토타입 메서드는 우리의 요구 사항을 충족할 수 없지만 이 클래스 라이브러리와 분리될 수 없으므로 현재 프로토타입에서 하나 이상의 속성이나 함수를 다시 작성해야 합니다. 추가 코드의 형식은 다음과 같습니다. 이전 추가 기능을 덮어쓰고 다시 작성합니다.
코드를 복사합니다. 코드는 다음과 같습니다.

//이전 계산기의 add() 함수 재정의
Calculator.prototype.add = function (x, y) {
return x y this.tax
}; 🎜 >var calc = new Calculator();
alert(calc.add(1, 1))


이런 식으로 계산한 결과에는 원래 값보다 세금이 하나 더 추가됩니다. 하나의 값이지만 주의할 점이 하나 있습니다. 다시 작성한 코드는 이전 코드를 덮어쓸 수 있도록 마지막에 배치해야 합니다.

프로토타입 체인
프로토타입을 연결하기 전에 먼저 코드 조각을 삽입합니다.


function Foo() {
this.value = 42
}
Foo.prototype = {
method: function() {}
};

function Bar() {}

// Bar의 프로토타입 속성을 Foo의 인스턴스 객체로 설정합니다.
Bar.prototype = new Foo(); >Bar.prototype .foo = 'Hello World';

// Bar.prototype.constructor를 Bar 자체로 수정
Bar.prototype.constructor = Bar;

var test = new Bar() / / Bar의 새 인스턴스 생성

// 프로토타입 체인
test [Bar 인스턴스]
Bar.prototype [Foo 인스턴스]
{ foo: 'Hello World ' }
Foo.prototype
{method: ...};
Object.prototype
{toString: ... /* 등 */};
위의 예에서 테스트 개체는 Bar.prototype 및 Foo.prototype에서 상속되므로 Foo의 프로토타입 메서드 메서드에 액세스할 수 있습니다. 동시에 프로토타입에 정의된 Foo 인스턴스 속성 값에 액세스할 수도 있습니다. new Bar()는 새로운 Foo 인스턴스를 생성하지 않지만 프로토타입에서 이를 재사용하므로 모든 Bar 인스턴스는 동일한 value 속성을 공유합니다.

속성 조회:
객체의 속성을 찾을 때 JavaScript는 지정된 이름의 속성을 찾을 때까지, 검색이 프로토타입 체인의 맨 위에 도달할 때까지 프로토타입 체인을 위쪽으로 순회합니다. is, Object.prototype - 그러나 지정된 속성을 여전히 찾을 수 없으면 정의되지 않음이 반환됩니다. 예를 살펴보겠습니다.
코드 복사 코드는 다음과 같습니다.

function foo() {
this.add = function (x, y) {
return x y; }

foo.prototype.add = 함수(x, y) {
return x y 10;
}

Object.prototype.subtract = 함수(x, y)
return x - y;
}

var f = new foo();
alert(f.add(1, 2)) //결과는 13이 아니라 3입니다.
alert(f.subtract(1, 2)); //결과는 -1입니다.


코드를 실행하면 뺄셈이 결과를 얻기 위해 상향 검색을 설치한다는 것을 알 수 있습니다. , 하지만 add 방법이 조금 다른 것 같아요. 제가 강조하는 점은 속성을 검색할 때 먼저 자신의 속성을 검색한다는 것입니다. 프로토타입이 없으면 프로토타입을 검색합니다. 를 사용하여 Object의 프로토타입에 삽입합니다. 따라서 특정 수준에서는 속성을 순회할 때 효율성도 문제가 됩니다.

또 한 가지 주의해야 할 점은 프로토타입에 모든 유형의 객체를 할당할 수 있지만 원자 유형 값을 할당할 수는 없다는 것입니다. 예를 들어 다음 코드는 유효하지 않습니다.


function Foo() {}
Foo.prototype = 1; 잘못된


hasOwnProperty 함수:
hasOwnProperty는 Object.prototype의 메서드입니다. hasOwnProperty가 있기 때문에 객체에 프로토타입 체인의 속성 대신 사용자 지정 속성이 포함되어 있는지 확인할 수 있습니다. 프로토타입 체인을 조회하지 않고 속성을 처리하는 유일한 함수입니다.


// Object.prototype 수정
Object.prototype .bar = 1;
var foo = {goo: 정의되지 않음};

foo.bar; // 1
'bar' // true

foo.hasOwnProperty('bar'); // false
foo.hasOwnProperty('goo'); // true


객체를 탐색할 때 hasOwnProperty만이 정확하고 예상되는 결과를 제공할 수 있습니다. 속성이 유용할 수 있습니다. 객체 자체에 정의된 속성 외에 프로토타입 체인의 속성을 제외할 수 있는 다른 방법은 없습니다.

하지만 역겨운 점이 있습니다. JavaScript는 hasOwnProperty가 불법적으로 점유되는 것을 방지하지 않으므로 객체에 이 속성이 있는 경우 올바른 결과를 얻으려면 외부 hasOwnProperty 함수를 사용해야 합니다.


var foo = {
hasOwnProperty: function() {
return false;
},
bar: 'Here be Dragons'
};

foo.hasOwnProperty('bar'); // 항상 false를 반환합니다.

// {} 객체의 hasOwnProperty를 사용하고 상단과 하단을 foo로 설정합니다
{}.hasOwnProperty.call(foo, 'bar') // true


hasOwnProperty는 객체에 속성이 존재하는지 확인할 때 사용할 수 있는 유일한 방법입니다. 동시에 for in 루프를 사용하여 객체를 탐색할 때 항상 hasOwnProperty 메서드를 사용하는 것이 좋습니다. 이렇게 하면 프로토타입 객체 확장으로 인한 간섭을 피할 수 있습니다.


// Object.prototype 수정
Object.prototype.bar = 1 ;

var foo = { moo: 2};
for(var i in foo) {
console.log(i); // bar 및 moo
}


us for in 문의 동작을 변경할 수 있는 방법이 없으므로 결과를 필터링하려면 hasOwnProperty 메소드만 사용할 수 있습니다.


코드 복사 코드는 다음과 같습니다.

// foo 변수는 위 예의 변수입니다.
for(var i in foo) {
if (foo.hasOwnProperty(i)) {
console.log(i );
}
}

이 버전의 코드가 코드를 작성하는 유일한 올바른 방법입니다. hasOwnProperty를 사용했기 때문에 이번에는 moo만 출력됩니다. hasOwnProperty를 사용하지 않으면 기본 객체 프로토타입(예: Object.prototype)이 확장될 때 이 코드가 중단될 수 있습니다.

요약: hasOwnProperty를 사용하는 것이 좋습니다. 코드가 실행되는 환경에 대해 어떠한 가정도 하지 않으며, 네이티브 객체가 확장되었는지 여부도 가정하지 않습니다.

요약
프로토타입은 개발 코드를 크게 풍부하게 해주었지만, 일상적인 사용 중에 위에서 언급한 몇 가지 주의 사항에 주의를 기울여야 합니다.
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

뜨거운 기사 태그

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Genshin Impact 버전 4.4의 새로운 맵 소개 Genshin Impact 버전 4.4의 새로운 맵 소개 Jan 31, 2024 pm 06:36 PM

Genshin Impact 버전 4.4의 새로운 맵 소개

스코프 체인과 프로토타입 체인이란 무엇입니까? 스코프 체인과 프로토타입 체인이란 무엇입니까? Nov 13, 2023 pm 01:46 PM

스코프 체인과 프로토타입 체인이란 무엇입니까?

프로토타입과 프로토타입 체인이란 무엇입니까? 프로토타입과 프로토타입 체인이란 무엇입니까? Nov 09, 2023 pm 05:59 PM

프로토타입과 프로토타입 체인이란 무엇입니까?

Go 언어와 Python의 성능 비교: 고성능 프로그래밍에 더 적합한 언어는 무엇입니까? Go 언어와 Python의 성능 비교: 고성능 프로그래밍에 더 적합한 언어는 무엇입니까? Jan 30, 2024 am 08:13 AM

Go 언어와 Python의 성능 비교: 고성능 프로그래밍에 더 적합한 언어는 무엇입니까?

프로토타입과 프로토타입 체인의 차이점은 무엇입니까 프로토타입과 프로토타입 체인의 차이점은 무엇입니까 Nov 09, 2023 pm 04:48 PM

프로토타입과 프로토타입 체인의 차이점은 무엇입니까

올바른 프로그래밍 언어 선택: Go와 Python을 비교하여 프로젝트 요구 사항에 가장 적합한 선택을 결정하세요. 올바른 프로그래밍 언어 선택: Go와 Python을 비교하여 프로젝트 요구 사항에 가장 적합한 선택을 결정하세요. Jan 30, 2024 am 08:00 AM

올바른 프로그래밍 언어 선택: Go와 Python을 비교하여 프로젝트 요구 사항에 가장 적합한 선택을 결정하세요.

국내 무료 프로그래밍 툴이 인기가 많아요! 칭화대학교 박사팀이 개발한 이 제품은 응답 지연이 짧고 정확도가 높습니다. 국내 무료 프로그래밍 툴이 인기가 많아요! 칭화대학교 박사팀이 개발한 이 제품은 응답 지연이 짧고 정확도가 높습니다. Jan 31, 2024 pm 05:03 PM

국내 무료 프로그래밍 툴이 인기가 많아요! 칭화대학교 박사팀이 개발한 이 제품은 응답 지연이 짧고 정확도가 높습니다.

js 프로토타입과 프로토타입 체인의 기능은 무엇입니까? js 프로토타입과 프로토타입 체인의 기능은 무엇입니까? Nov 09, 2023 pm 04:56 PM

js 프로토타입과 프로토타입 체인의 기능은 무엇입니까?

See all articles