2012-12-14 5 views
1

JavaScript로 캔버스 용 라이브러리 내부에서 사용할 작은 구조를 만들려고합니다. 다음JavaScript - 유연한 인수

BoundingBox = function(x, y, w, h) { 

    if('object' === typeof x) { 

     if(! 'x' in x) throw new Error('Property "x" missing'); 
     if(! 'y' in x) throw new Error('Property "y" missing'); 
     if(! 'w' in x) throw new Error('Property "w" missing'); 
     if(! 'h' in x) throw new Error('Property "h" missing'); 

     this.x = x.x; 
     this.y = x.y; 
     this.w = x.w; 
     this.h = x.h; 

    } else { 

     if(null == x) throw new Error('Parameter 1 is missing'); 
     if(null == y) throw new Error('Parameter 2 is missing'); 
     if(null == w) throw new Error('Parameter 3 is missing'); 
     if(null == h) throw new Error('Parameter 4 is missing'); 

     this.x = x; 
     this.y = y; 
     this.w = w; 
     this.h = h; 
    } 
}; 

과 :

var bb1 = new BoundingBox(0, 0, 200, 100); 

var bb2 = new BoundingBox({ 
    x: 0, 
    y: 0, 
    w: 200, 
    h: 100 
}); 

var bb3 = new BoundingBox(bb2); 

인가 나는 우리가 컴파일 된 언어처럼 하나 여러 인수가이 구조를 만들 때 전달 된 인수, 또는 특성이 매개 변수에 대응하는 객체를 싶습니다 이것을하는 청결한 방법? 우리가 객체를 사용하는 경우, "x"를 객체로 사용하는 것은 정말로 이상하게 보인다.

그리고 두 번째 질문이 있습니다. 노력을 기울이는 데 오류가 있습니까? 코드의 크기를 두 배로 늘리며 읽기 및 쓰기가 더 길어지고 속성이 공개되어 있으므로 null 또는 정의되지 않은 값을 갖는 것을 완전히 보호하지는 않습니다. 당신의 도움 :) 내가 그 끔찍하지만, 자바 스크립트, 과부하 모든 기능을 사용할 수있는 인수의 VAR을 통해 더 일반적으로 수행됩니다 생각하지 않는다

+0

당신은 간단한'overload' 기능을 만들 수 있습니다

​var overload = function(oldFunc, types, newFunc) { return function() { var suffice = Array.prototype.every.call(arguments, function(v, i) { return typeof v === types[i]; }); return (suffice ? newFunc : oldFunc).apply(this, arguments); }; }; 

사용법 (: http://jsfiddle.net/m2cRK/1/ 여기 재 할당이 필요하지 않는 기능입니다))', 여기서'types'는 새롭게 선언 된 함수의'typeof' 값의 배열입니다. 그런 다음 과부하 논리와 다른 기능을 분리 할 수 ​​있습니다. – pimvdb

+0

답변 해 주셔서 감사합니다. 나는 당신이 마음에있는 것을 이해하지 못합니다. – Virus721

답변

2

에 대한

감사합니다.

function BoundingBox(){ 

//do named functions with constructors. It sets the constructor.name 
//property in instances, which can be handy sometimes 

    if(typeof arguments[0] === 'object'){ 
     var coordsObj = arguments[0]; 
    } 
    else { 
     coordsObj = {} //no need for var dec even when upper if doesn't evaluate 
     coordsObj.x = arguments[0]; 
     coordsObj.y = argumetns[1]; 
     //...etc. 
    } 
    //laziest way to make those publicly available. 
    this.constructor.prototype = coordsObj; 
} 

귀하의 매개 변수를 테스트하는 한, 나는 긴장을 풀 것입니다. try/catch로 포장하여 params에 문제가 있거나 외부 소스에 의존하지 않는 함수에서 데이터를 신뢰하는 방법을 배웁니다. 동적 유형 지정은 앱을 통해 데이터의 흐름을 인식하고 모든 동적 캐스팅 규칙을 잘 이해하여 무언가가 잘못되었을 때 어떤 일이 벌어지고 있는지 이해할 수있을 때 무서워하지 않습니다. 당신도 엄격한 타입 패러다임

에 있어야하는 당신의 양심
+0

답변 해 주셔서 감사합니다! "평가할 수없는 상반신이더라도 var dec을 필요가 없다"는 것은 정확히 무슨 뜻입니까? – Virus721

+0

또한 내 객체에 메서드가있는 경우'this.constructor.prototype = coordsObj; '를 사용하면 해당 메서드가 제거되지 않을까요? – Virus721

+0

if 조건이 true가 아니더라도 var가 선언 된대로 계산되므로 if/else에서 두 번 선언 할 필요가 없습니다. 프로토 타입은 메소드가 인스턴스에 존재하지 않아 실제로 인스턴스의 어떤 것도 겹쳐 쓰지 않도록 백업 오브젝트와 같은 역할을합니다. 그래서 생성자 프로토 타입에 메소드를 추가 할 수 있으며 이미 생성 한 인스턴스는 메소드에 액세스 할 수 있습니다. –

0

다음과 같이 overload 기능에 대한 내 생각은 : 당신은 typeof의 배열로 (함수를 받아들이는 기능 overload, 그 서명이 새로운 기능을 만들 수 있습니다 값). 반환 된 함수는 현재 호출이이 서명과 일치하는지 여부를 확인하고이 경우 새 함수를 호출합니다. 그렇지 않으면 이전 함수를 호출합니다.

이렇게하면 여러 번 패치하여 오버로드 할 수 있습니다. 서로 다른 기능과 실제 오버로딩 로직의 정의는 이러한 방식으로 분리 될 수 있습니다. http://jsfiddle.net/m2cRK/을 참조하십시오. 이러한`(FUNC, 유형, newFunc로 서명,

// The end of the chain, e.g. a function that throws a "no overload" error 
var foo = overloadStart(); 

// Function 1 
foo = overload(foo, ["number", "number"], function(a, b) { 
    return a + b; 
}); 

// Function 2 
foo = overload(foo, ["object"], function(obj) { 
    return obj.a + obj.b; 
}); 


foo(1, 2);   // 3 
foo({ a: 1, b: 2 }); // 3 
foo("bar");   // error