생성자에서 직접 메소드를 정의하는 것과 프로토 타입을 사용하는 이점은 무엇입니까? [복제]
이 질문에는 이미 답변이 있습니다.
나는 이것들 중 다른 것을 사용하는 것의 이점이 있는지 궁금하고, 어떤 방법으로 가야합니까?
생성자 접근 방식 :
var Class = function () {
this.calc = function (a, b) {
return a + b;
};
};
프로토 타입 접근법 :
var Class = function () {};
Class.prototype.calc = function (a, b) {
return a + b;
};
프로토 타입을 사용하여 메소드 정의가 클래스와 분리되어있는 것이 마음에 들지 않으며, 첫 번째 방법으로 사용해야하는 특별한 이유가 있는지 모르겠습니다.
또한 함수 리터럴을 사용하여 함수 정의보다 "클래스"를 정의하면 어떤 이점이 있습니까?
var Class = function () {};
vs
function Class () {};
감사!
프로토 타입 체인을 통해 상속되는 메소드는 다음과 같이 모든 인스턴스에서 보편적으로 변경 될 수 있습니다.
function Class () {}
Class.prototype.calc = function (a, b) {
return a + b;
}
// Create 2 instances:
var ins1 = new Class(),
ins2 = new Class();
// Test the calc method:
console.log(ins1.calc(1,1), ins2.calc(1,1));
// -> 2, 2
// Change the prototype method
Class.prototype.calc = function () {
var args = Array.prototype.slice.apply(arguments),
res = 0, c;
while (c = args.shift())
res += c;
return res;
}
// Test the calc method:
console.log(ins1.calc(1,1,1), ins2.calc(1,1,1));
// -> 3, 3
메소드 변경이 두 인스턴스에 어떻게 적용되는지 확인하십시오. 때문이다 ins1
과 ins2
같은 공유 calc()
기능을. 생성하는 동안 생성 된 퍼블릭 메서드로이를 수행하려면 생성 된 각 인스턴스에 새 메서드를 할당해야합니다. 이는 까다로운 작업입니다. 이 때문입니다 ins1
및 ins2
자신의 개별적으로 만든 것입니다 calc()
기능을.
생성자 내에서 메소드를 작성하는 또 다른 부작용은 성능이 저하된다는 것입니다. 생성자 함수가 실행될 때마다 각 메소드를 작성해야합니다. 프로토 타입 체인의 메소드는 한 번 작성된 후 각 인스턴스에서 "상속"됩니다. 동전의 반대편에서, 공개 메소드는 "비공개"변수에 액세스 할 수 있으며, 상속 된 메소드로는 불가능합니다.
귀하의 function Class() {}
vs var Class = function () {}
질문에 관해서는, 전자는 실행 전에 현재 범위의 상단에 "상승"됩니다. 후자의 경우 변수 선언이 들어 있지만 할당은 아닙니다. 예를 들면 다음과 같습니다.
// Error, fn is called before the function is assigned!
fn();
var fn = function () { alert("test!"); }
// Works as expected: the fn2 declaration is hoisted above the call
fn2();
function fn2() { alert("test!"); }
프로토 타입 방식의 장점은 효율성입니다. calc()
모든 Class
객체 간에 공유되는 함수 객체 가 하나 있습니다 ( Class
생성자 를 호출하여 생성 된 객체를 의미합니다 ). 다른 방법 (생성자 내에서 메소드 할당)은 생성자를 Class
호출 할 때 더 많은 메모리를 사용하고 처리 시간이 더 걸리는 모든 개체에 대해 새로운 함수 개체를 만듭니다 Class
. 그러나이 접근 방식은 장점이 있습니다. calc()
메소드는 생성자 내의 로컬 변수에 액세스 할 수 있으므로이를 활용할 수 있습니다.
function Class() {
var calcCallCount = 0;
this.calc = function (a, b) {
++calcCallCount;
alert("Calc called " + calcCallCount + " times");
return a + b;
};
};
var Class = function() {...}
vs function Class() {...}
에 관해서는 , 일반적으로 후자가 더 좋습니다.이 함수에는 이름이 있다는 의미이기 때문에 디버깅 할 때 유용 할 수 있습니다. 또 다른 차이점은 후자의 버전 ( 함수 선언 )이 게양되어 있다는 것입니다. 즉, 정의 직후뿐만 아니라 정의 된 범위 내 어디에서나 사용할 수 있습니다. 그러나 어떤 사람들 은 어디에서나 전자 ( 함수 표현 )를 선호합니다 .
var YourClass = function(){
var privateField = "somevalue";
this.publicField = "somevalue";
this.instanceMethod1 = function(){
//you may access both private and public field from here:
//in order to access public field, you must use "this":
alert(privateField + "; " + this.publicField);
};
}
YourClass.prototype.instanceMethod2 = function(){
//you may access only public field 2 from this method, but not private fields:
alert(this.publicField);
//error: drawaback of prototype methods:
alert(privateField);
};
프로토 타입 방법의 장점 :
프로토 타입을 통해 메소드를 정의하면 모든 YourClass 인스턴스간에 메소드가 공유됩니다. 결과적으로 그러한 인스턴스의 총 크기는 생성자에서 메소드를 정의 할 때보 다 <입니다. 프로토 타입을 통한 메소드 정의가 html 페이지의 전체 크기를 줄이고 결과적으로로드 속도를 줄이는 방법을 보여주는 테스트가 있습니다.
프로토 타입을 통해 정의 된 메소드의 또 다른 장점은 상속 된 클래스를 사용할 때 해당 메소드를 대체 할 수 있으며 파생 클래스의 대체 된 메소드에서 동일한 이름으로 기본 클래스의 메소드를 호출 할 수 있지만 생성자에 정의 된 메소드를 사용하여 너는 이것을 못해.
우선 다음과 같이 객체 리터럴을 사용해야합니다.
var Class = {
calc: function (a, b) {
return a + b;
}
};
이 표기법은 더 깨끗하고 Javascript 객체에서 미리 정의 된 클래스와 같은 레시피에서 지원되는 것이 아니라 해시임을 분명히합니다.
정의의 차이점은 프로토 타입에 메소드를 추가하면 모든 인스턴스에 대해 하나의 메소드 만 메모리에 작성된다는 것입니다. 따라서 일반 메소드와 여러 인스턴스에서 작성 / 사용되는 오브젝트가있는 경우 메소드를 프로토 타입에 추가해야합니다.
'IT' 카테고리의 다른 글
URL 인코딩은 "&"(앰퍼샌드)를 "&"HTML 엔터티로 인식 (0) | 2020.03.18 |
---|---|
Express-js가 정적 파일을 가져올 수없는 이유는 무엇입니까? (0) | 2020.03.18 |
android studio에서 gradle을 업데이트하는 방법은 무엇입니까? (0) | 2020.03.18 |
널 입력 가능하도록 열 변경 (0) | 2020.03.18 |
img src SVG 채우기 색상 변경 (0) | 2020.03.18 |