이것은 JavaScript입니다. 당신이 그것을 더 잘 얻을 때 당신은 종종 이와 같은 딜레마를 부정하는 데 도움이되는 중간 도로가 있음을 알 수 있습니다. 또한 컴파일되지 않은 런타임이 없기 때문에 누군가 사용하려고 할 때 지원되지 않는 '유형'이 무언가에 걸리거나 중단되는지 여부는 중요하지 않습니다. 잘못 사용하면 고장납니다. 파산했을 때 숨겨 지거나 반쯤 작동하게한다고해서 무언가가 파손되었다는 사실은 바뀌지 않습니다.
따라서 케이크를 먹고 먹으며 올바른 이름으로 모든 올바른 장소에 올바른 세부 사항과 함께 모든 것을 실제로, 분명하게 유지하여 유형 혼란과 불필요한 파손을 피하는 법을 배우십시오.
우선, 유형을 확인하기 전에 오리를 한 줄로 모으는 습관을들이는 것이 좋습니다. 가장 간결하고 가장 효율적인 (그러나 항상 기본 생성자가 염려되는 곳은 아니지만)해야 할 일은 프로토 타입을 먼저 쳐서 지원되는 유형이 무엇인지 신경 쓰지 않아도됩니다.
String.prototype.pullRabbit = function(){
//do something string-relevant
}
HTMLElement.prototype.pullRabbit = function(){
//do something HTMLElement-relevant
}
Magician.pullRabbitFrom = function(someThingy){
return someThingy.pullRabbit();
}
참고 : 모든 것이 Object에서 상속되므로 Object 에이 작업을 수행하는 것은 잘못된 형식으로 널리 간주됩니다. 나는 개인적으로 기능도 피할 것입니다. 어떤 사람들은 나쁜 정책이 아닐 수도있는 네이티브 생성자의 프로토 타입을 건 드리는 것에 대해 불안감을 느낄 수 있지만, 자신의 객체 생성자와 함께 작업 할 때 예제가 여전히 제공 될 수 있습니다.
덜 복잡한 응용 프로그램에서 다른 라이브러리의 무언가를 클로버하지 않을 가능성이있는 특정 용도의 메소드에 대해서는이 방법에 대해 걱정하지 않지만 JavaScript가 아닌 경우 기본 메소드에서 일반적으로 지나치게 일반적으로 주장하는 것을 피하는 것이 좋습니다. 오래된 브라우저에서 최신 메소드를 정규화하지 않는 한해 야합니다.
다행스럽게도 항상 타입이나 생성자 이름을 메소드에 미리 매핑 할 수 있습니다 (생성자 속성의 toString 결과에서 구문 분석해야하는 <object> .constructor.name이없는 IE <= 8에주의하십시오). 당신은 여전히 생성자 이름을 검사하는 중입니다 (유형은 객체를 비교할 때 JS에서 쓸모가 없습니다). 그러나 적어도 거대한 switch 문이나 메소드의 모든 호출에서 if / else 체인보다 더 넓을 수 있습니다. 다양한 개체.
var rabbitPullMap = {
String: ( function pullRabbitFromString(){
//do stuff here
} ),
//parens so we can assign named functions if we want for helpful debug
//yes, I've been inconsistent. It's just a nice unrelated trick
//when you want a named inline function assignment
HTMLElement: ( function pullRabitFromHTMLElement(){
//do stuff here
} )
}
Magician.pullRabbitFrom = function(someThingy){
return rabbitPullMap[someThingy.constructor.name]();
}
또는 동일한 맵 접근 방식을 사용하여 다른 객체 유형의 'this'구성 요소에 액세스하여 상속 된 프로토 타입을 건드리지 않고 메소드 인 것처럼 사용하려는 경우 :
var rabbitPullMap = {
String: ( function(obj){
//yes the anon wrapping funcs would make more sense in one spot elsewhere.
return ( function pullRabbitFromString(obj){
var rabbitReach = this.match(/rabbit/g);
return rabbitReach.length;
} ).call(obj);
} ),
HTMLElement: ( function(obj){
return ( function pullRabitFromHTMLElement(obj){
return this.querySelectorAll('.rabbit').length;
} ).call(obj);
} )
}
Magician.pullRabbitFrom = function(someThingy){
var
constructorName = someThingy.constructor.name,
rabbitCnt = rabbitPullMap[constructorName](someThingy);
console.log(
[
'The magician pulls ' + rabbitCnt,
rabbitCnt === 1 ? 'rabbit' : 'rabbits',
'out of her ' + constructorName + '.',
rabbitCnt === 0 ? 'Boo!' : 'Yay!'
].join(' ');
);
}
모든 언어 IMO에서 좋은 일반적인 원칙은 실제로 트리거를 당기는 코드에 도달하기 전에 이와 같은 분기 세부 정보를 정렬하는 것입니다. 그렇게하면 최고의 API 레벨에 관련된 모든 플레이어를 쉽게 볼 수있을뿐만 아니라 누군가가 관심을 가질만한 세부 정보를 찾을 수있는 위치를 쉽게 정렬 할 수 있습니다.
참고 : 이것은 실제로 아무도 RL을 사용하지 않는다고 가정하기 때문에 모두 테스트되지 않았습니다. 오타 / 버그가 있다고 확신합니다.