2013-07-04 3 views
11

다음 두 가지 자바 스크립트 프로토 타입 간의 기능상의 차이점은 무엇이며 다른 하나를 선택하면 어떤 이점이 있습니까?자바 스크립트 프로토 타입 정의

옵션 1 :

Person.prototype.sayName = function(name) { 
    alert(name); 
} 

옵션 2 :

Person.prototype = { 
    sayName: function(name) { 
     alert(name); 
    } 
} 

내가 특정 기능을 부수고에서 옵션 2 개 결과가 암시 적 프로토 타입에 바인딩되는 가정에서 수정 건가요 ?

+0

[이 프로토 타입 선언의 차이점은 무엇입니까?] (http://stackoverflow.com/questions/16773061/what-is-the-difference-between-the-prototype-declaration) – Bergi

답변

5

옵션 2가 프로토 타입에 암시 적으로 바인딩 된 특정 기능을 제거한다고 가정합니다.

예. 암시 적으로 바인딩 된 속성은 constructor 속성이지만 거의 필요하지 않습니다.

기능상의 차이점은 무엇입니까?

옵션 1은 기존 프로토 타입을 확장하는 것입니다.프로토 타입 개체에서 상속하는 Person 인스턴스가 이미있는 경우 sayName 메서드도 사용할 수 있습니다. 옵션 2를 사용하면 새 프로토 타입은 덮어 쓰기 후에 인스턴스화 된 객체에만 사용됩니다.

다른 하나를 선택하면 어떤 이점이 있습니까?

이들은 이제 스스로 설명해야합니다. 옵션 1 (확장)은 더 깨끗한 것으로 간주되며, 외국/알려지지 않은/원시 프로토 타입을 수정하는 경우 필수 항목입니다. 여전히 객체 리터럴 구문을 더 좋아한다면, 당신은 기존의 프로토 타입을 확장 할 Object.assign을 사용하는 것이 좋습니다 옵션 2.

을 피하십시오 : 당신은 사전 ES6 환경 polyfill Object.assign해야 할 수도 있습니다

Object.assign(Person.prototype, { 
    sayName: function(name) { 
     alert(name); 
    } 
}); 

. 또는 $.extend 또는 _.extend도 올바르게 작동합니다. 분명히 좋아하는 라이브러리에는이를위한 도우미 기능이 있습니다.

+0

왜 지구상에서 옵션 1을 더 깨끗하게해야하는지. 그것은 옵션 2가 깨끗한 슬레이트로 시작하여 말하는 것입니다. –

+1

@AlexMills : 당신이 그렇지 않으면 덮어 쓰게 될 프로토 타입에 어떤 속성이 있는지 알 필요가 없으므로 (코드가 호출되는 위치와 관계없이) 코드가 중단되지 않습니다. 더 간단하고 오류가 발생하기 쉽고 포워드 호환이 가능합니다. 물론 처음부터 프로토 타입 객체를 만들면 객체 리터럴을 사용할 수도 있지만 대부분의 사람들은 표준'constructor' 속성을 잊어 버립니다. – Bergi

2

첫 번째 기능은 하나 또는 두 개의 추가 기능에 적합하지만 많은 기능을 갖춘 완전히 새로운 프로토 타입을 정의하는 것은 매우 반복적입니다. 반면에 후자를 사용하면 앞서 언급 한 프로토 타입의 기존 정의를 모두 파기합니다.

실제로는 Objective-C의 범주와 같이 Array 및 Math 등에서 추가 기능을 정의하는 데 처음 사용했습니다. 후자는 "클래스 정의"로 사용합니다.

+1

기존의 코드 라이브러리 (예 : 수학)에 프로토 타입을 완전히 휴지통으로 만들지는 않겠지 만 처음부터 새 라이브러리를 만들 때 프로토 타입을 휴지통으로 버려야하는 이유가 무엇입니까? 즉, 새로운 프로토 타입을 만들 때 이미 어떤 함수가 첨부되어 있습니까? 아니면 그냥 빈 자리 표시 자입니까? –

+1

@RichardKeller 함수의 프로토 타입을 Object의 프로토 타입으로 덮어 씁니다. 따라서 new this.constructor()를 사용하여'this'의 새 인스턴스를 만들 수 없습니다 : http://phrogz.net/JS/classes/OOPinJS2 .html – HMR

+1

새로운 프로토 타입으로 꽤 안전합니다. Google 크롬 콘솔에서 실험을 시도했지만 중요한 것을 파괴 할 수는 없습니다. 이 [link] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto)를 참조하십시오. – isaach1000

3

두 번째 사람은 person.prototype을 개체로 덮어 씁니다.

방법 1 :

Object.toString=function(){ 
    return "Object to string"; 
} 
var Person = function(){ 
}; 
Person.toString=function(){ 
    return "Person to string"; 
} 
Person.prototype.sayName=function(){} 
console.log(Person.prototype.constructor.toString());// "Person to string" 

방법 2 : 차이가 당신이 모두가 prototype에 기능을 추가하는 것입니다 Person.prototype.sayName

Object.toString=function(){ 
    return "Object to string"; 
} 
var Person = function(){ 
}; 
Person.toString=function(){ 
    return "Person to string"; 
} 
Person.prototype = { 
    sayName:function(){} 
} 
console.log(Person.prototype.constructor.toString());// "Object to string" 
0

간단한 단어에. 새로운 기능을 추가하기 만하면됩니다.

두 번째 Person.prototype = {} 여기에서 새로운 전체 개체를 만들고 prototype에 할당합니다. 그래서 새 객체를 만들거나 prototype을 새 객체로 덮어 씁니다.

첫 번째 방법은 원하는대로 많은 기능을 추가하는 것이 좋습니다 은 주문형입니다. 당신은 시간에 각각 하나씩 추가 할 수 있습니다. 그래서 프로그램이 단순하고 응용 프로그램 객체가 많은 함수 나 객체를 공유하지 않을 때 좋다고 생각합니다.

두 번째 방법은 응용 프로그램 개체가 개체 (또는 @isaach가 Math functions에서 말한 함수 그룹)을 공유하는 경우에 유용합니다.

1

기존 생성자 인스턴스는 계속 이전 프로토 타입 개체를 가리 킵니다. 생성 된 새 인스턴스는 새 프로토 타입 객체를 가리 킵니다. 옵션 2 이상 옵션 1의


장점은 당신이 다시 설정 constructor 속성 필요가 없습니다 당신이 나를 위해 거대한 하나 개의 들여 쓰기 수준을 저장하는 것이 간단합니다.

난 그냥 로컬 변수에 속성을 부여, 반복을 저장하려면

var method = Person.prototype; 

method.getAge = function() { 
    return this.age; 
}; 

method.getName = function() { 
    return this.name; 
}; 

또한 일반적인 선택 사항은 method보다 더 짧은 fn (jQuery를) 및 p.

관련 문제