각 함수를 실행하여 결과를 얻으면, 프로토타입을 학습한 후 다음과 같은 방법을 사용하여 코드를 아름답게 만들 수 있습니다.
프로토타입을 사용하기 전에 코드를 약간 수정해야 합니다.
그런 다음 Calculator 객체의 프로토타입 속성에 객체 리터럴을 할당하여 Calculator 객체의 프로토타입을 설정합니다.
두 번째 방법은 프로토타입 프로토타입을 할당할 때 함수가 즉시 실행되는 표현식을 사용하는 것인데, 형식은 다음과 같습니다.
장점은 이전 게시물에서 이미 알려져 있습니다. 즉, 비공개 함수를 캡슐화하고 간단한 사용 이름을 반환 형식으로 노출하여 공개/비공개 효과를 얻을 수 있다는 것입니다.
위의 프로토타입을 사용할 때 프로토타입 개체를 한 번에 설정하는 데 한계가 있습니다. 프로토타입은 별도로.
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를 사용하는 것이 좋습니다. 코드가 실행되는 환경에 대해 어떠한 가정도 하지 않으며, 네이티브 객체가 확장되었는지 여부도 가정하지 않습니다.
요약
프로토타입은 개발 코드를 크게 풍부하게 해주었지만, 일상적인 사용 중에 위에서 언급한 몇 가지 주의 사항에 주의를 기울여야 합니다.