2012-08-31 3 views
16

bar와 foo의 동등성에 대한 긍정적 인 테스트를 얻는 방법은 무엇입니까?자바에서 함수 평등을 테스트하는 방법

foo = function() { 
    a = 1; 
}; 

bar = function() { 
    a = 1; 
}; 

if (foo === bar) alert('baz'); 
if (foo == bar) alert('qux'); 

위의 두 조건은 모두 거짓입니다.

업데이트 - 나는 기능 평등

나는 Publish/Subscribe의 프레임 워크를 구축하고 주제에 구독을 취소하는 중위 콜백을 전달해야하고 테스트해야하는 이유를 요청한다.

바이올린을 참조하십시오 http://jsfiddle.net/jamiefearon/hecMS/47/

+0

값을 반환 ?? 돌아온다; 있어야 할 곳에 없는? – frenchie

+2

왜 그런지 설명하면 도움이되는 답변과 의견을 제공하는 데 도움이 될 수 있습니다. – Pointy

+0

그래서 두 함수의 내용이 정확히 같은지 확인하고 싶습니까? 왜 정확히 이것을해야합니까? –

답변

3
당신은 두 변수가 동일한 함수 객체에를 참조 있는지 여부를 테스트 할 수 있습니다, 당신은 문자열로 기능을 전환하고 정말 정확히 같은 있다면 볼 수 있습니다

, 그러나 두 함수가 이 똑같은 것을 수행하는지 여부를 확인하려고 시도하면이 조금 더 어려워 지거나 더 힘들어 질 수 있습니다.

minifier가 상당한 양의 정적 분석을하기 때문에 minifier를 통해 한 쌍의 함수를 실행하는 것은 흥미로울 것입니다.

+2

조금 더 힘들지는 않지만 사실 불가능합니다. – duri

+2

@duri 글쎄, 나는 뭔가를 "불가능하다"는 것이 굴욕감을주는 좋은 방법이라고 말하는 것을 배웠다 :-)하지만 JavaScript와 같은 동적 언어의 완전한 정적 분석은 불가능합니다. – Pointy

+3

2 가지 함수가 동등한 가라는 질문은 프로그래밍보다는 수학과 관련이 있습니다.하지만 http://stackoverflow.com/questions/1132051/is-finding-the-equivalence-of-two-functions- undecidable – duri

0

기본적으로 일반적으로 불가능합니다. javascript에서 기능적 평등을 테스트 할 수있는 방법은 없습니다. 당신이 얻을 수있는 가장 가까운 것은 문자열을 평등하게 비교하는 것입니다.

+0

이것은 분명히 잘못되었습니다 –

1

이 기능이 필요한 것 같아 프로그램을 약간 재구성하는 것이 좋습니다. 이 같은 뭔가 일할 수 :

function baz(myInt) { return 3 + myInt; } 
function asd(a) { return 3 + a; } 

var foo = baz; 
foo(1); //returns 4 

var bar = baz; 
bar(3); //returns 6 

foo === bar; //true 

bar = asd; 
bar(3); //returns 6 

foo === bar; //false 
20

당신은 두 가지 기능의 내용이 정확히 동일 여부를 확인할 수 있습니다 그들에 toString를 호출 한 결과를 비교하여, 그러나 실패

var foo = function() { 
    a = 1; 
}; 

var bar = function() { 
    a = 1; 
}; 

alert(foo.toString() == bar.toString());​ 

다른 문자가 하나라도있는 경우. 반면에 두 가지 기능이 일 경우 같은 일을하는지 확인하는 것은 거의 불가능합니다.

+0

정확합니다. 완벽하게 일했습니다 ... – Basith

+25

그러나 이것은 또한 전혀 쓸모가 없습니다. –

+4

절대적으로! 그것은 lodash debounce와 같은 기능에 필수적입니다. – morels

13

문제는 함수에 대해 서로 다른 개념이 있다는 것입니다.

  • 참조 평등. 함수는 메모리의 어딘가에 저장되고 특정 주소에서부터 시작됩니다. 두 함수 이름 (본질적으로 내부 주소)은 두 주소가 같은 주소를 가리킬 경우 true이라는 참조 평등을 제공합니다. 하나를 지정할 때 문제가됩니다. bar = foo. 참조 평등은 JavaScript에서 사용됩니다.
  • 다른 답변에서 제안 된대로 소스 코드에서 평등합니다. 함수 본문에서 문자를 변경하면 작동하지 않습니다. 또한 toSource은 현재 (2014 년 현재) Firefox에서만 사용할 수 있습니다. W3C가 표준화되지 않았기 때문입니다.
  • 소스 코드의 문법적 동일성. 공백이나 주석의 수정을 막기 위해 추상 구문 트리를 사용할 수 있습니다. 람다 계산법에 정의 된 바와 같이 알파 등가성 (즉, 함수의 동등성, 변수가 일관되게 이름이 바뀌 었음)을 사용할 수 있지만, 동일한 방식으로 작동하는 경우 함수가 같을 때
  • Extensional equality이 있습니다.거기에 a theorem 거기에 함수의 확장 평등을 확인하는 알고리즘이 없다는 것을, 그래서 확실히 당신이 찾고있는 하나가 아니에요. 비록, JS보다는 좀 더 고급 언어 (당신이 중 하나가 기능을 손으로 동일 또는 프로그램이 컴파일되지 않습니다 증명)
  • 내포 평등과
  • 관측 평등 (this one is too advanced to explain)에있다.

그래서 평등이 무엇인지 생각해보십시오.

+4

각각의 예제를 추가 할 수 있다면 훌륭한 대답이 될 것입니다! –

0

간단한 접근 : 호출 할 때마다 고유 한 ID를 반환하도록 구독 API를 구현하면 해당 ID로 구독 취소 API를 호출하는 것처럼 간단합니다. 내부적으로 간단한 시나리오에서는 간단한 배열을 사용하여 모든 구독자를 저장하지만이 방법을 사용하면 저장해야합니다. ID는 단일 구독 통화마다 증분 할 수있는 간단한 카운터 일 수 있습니다.

: 당신은 모든 가입자에 게시 할 때

그래서 모든 가입자를 반복 {ID 가입자 '콜백 함수}.

고급 접근 방식 : 구독 API에서 간단한 함수 이름을 사용하는 대신 onMessage 함수가 있어야하는 클래스의 개체 (또는이 메서드에 지정할 이름)를 사용하십시오. 그런 다음 객체의 동일한 인스턴스를 API를 구독 취소하기 위해 간단히 전달하여 등록되지 않도록 할 수 있습니다. 가입자에게 알릴 필요가있을 때 모든 가입자의 instance.onMessage 기능을 호출 할 수 있습니다. 두 객체 참조를 비교하는 것은 쉽습니다. 당신이 이벤트

https://github.com/nodejs/node/blob/master/lib/events.js

을위한 Node.js를 소스에서 보면

3

당신은 핵심 팀이 === 구현 방법 나는 확실하지 않다 평등

에 대한 기능을 비교하는 ===을 사용하고 있음을 알 수있다 함수에 대해서는 두 개의 다른 함수가 동일한 toString() 결과를 가질 수 있으므로 이 아니길 바랍니다. LOL

+1

이것은 자바 스크립트의 표준 동작과 같은 참조 평등 확인을 사용합니다. https://github.com/nodejs/node/blob/master/lib/events.js#L329 – SimplGy

관련 문제