2012-07-17 7 views
6

이 질문 What are the best practices to follow when declaring an array in Javascript?하이재킹 된 JavaScript 배열에 함수를 추가 할 수 있습니까?

관련

이의이 "D. B. Cooper" 그들을 부르 자, 이제 클라이언트를 가정 해 봅시다되고, 다음 코드는 다른 자바 스크립트 코드를 먼저 실행해야합니다 첫 번째 요구 사항이 있습니다 또한

Array = function(){ 
    alert('Mwahahahaha'); 
}; 

을, Cooper는 사용자 정의 함수가 객체 (하이재킹 된 객체가 아님)에 추가되어야한다고 요구합니다. 여유 것이다

Array.prototype.coolCustomFunction = function(){ 
    alert('I have ' + this.length + ' elements! Cool!'); 
}; 

: Array이 unhijacked 경우 예를 들어, 이것은 함께 할 것

var myArray = []; 
myArray.coolCustomFunction(); 

그러나, 이것은 첫 번째 요구 사항과 호환되지 않습니다. 따라서 B. B. Cooper의 요구 사항을 어떻게 충족시킬 수 있습니까?

참고 : D.B. 심지어 해결책이 자신의 요구 사항을 충족시키는 데 도움이되도록 a test fiddle을 작성했습니다.


업데이트 :이 문제에 대한 unhijackable 크로스 브라우저 해결책을 찾기 위해 시도하십시오 도전을 좋아하는 분들을 위해 . 예를 들어, here's은 Array, Object, Array.prototype.constructor 및 Object.prototype.constructor를 가로채는 훨씬 더 하이재킹 된 테스트 케이스 (이 Bergi를 다시 포맷 해 주셔서 감사합니다)입니다. 지금까지는 브라우저 특정 솔루션이있을 수 있습니다 (Bergi's comment on his answer 참조). FF로 하이재킹하는 방법을 찾으면 알려주십시오.하지만 크로스 브라우저가 있는지 여부는 아직 명확하지 않습니다. 이것에 대한 해결책.

+2

형식은 SO – rjz

+2

에 새로운 포스터에 대한 연구 자료를 요구해야 다시 DB 쿠퍼의 요구 사항 문서를 보내기 모든 수요에 대한 사용 사례에 주장하고있다. :) – Quentin

+0

@Quentin : 당신이 그를 찾을 수 있다면, 그것은 좋은 옵션이 될 것입니다 :) – Briguy37

답변

2

무엇이든 Array 기능/생성자는, 배열 리터럴 구문은 항상 자신과 함께 "진짜"배열을 생성 할 것이다 [[프로토 타입]] 한 번,이 기본 배열 프로토 타입 객체 (로 설정 was a security vulnerability). 그래서, 당신은 항상

Object.getPrototypeOf([]) 

경우에도 Array 또는 [].constructor가 외부로 유출을 사용하여 해당 액세스 할 수 있습니다.당신이 in FF 다음 줄이 항상 작동하는 해결 방법을 사용하려면


(Brought D.B. down!)을 (물론 윌 Object가 납치 될 때 그 때의 정말 복잡 작동하지) (그리고하지 않습니다 hijackable) :이 질문의

[].__proto__.coolCustomFunction = coolCustomFunction; 
+0

흥미 롭! 나는 배열 객체의 생성자를 하이재킹하기로 결정했다 :'[] .constructor.prototype.constructor = ..', 그리고 그것은 Torsten의 해결책을 실패하게 만들었다. 그런 다음 Object를 납치하여 솔루션이 실패하게 만들었지 만'({}). constructor'과 함께 작동합니다. 그런 다음 Object 객체의 생성자 인'({}). constructor.prototype.constructor = ..'를 납치하여 모든 것을 실패하게했습니다. 그 시점에서, 나는 붙어있어, 아직 이것에 un-hijackable 해결책을 찾지 못했습니다 :) 여기에 업데이트 된 바이올린이 있습니다 : http://jsfiddle.net/briguy37/yXPJ8/8/ – Briguy37

+1

그건 정확히 내 라인이었습니다. 생각의 :-) 그러나, 나는 [읽을 수 있도록] (http://jsfiddle.net/yXPJ8/9/) [중독 된 바이올린을 재구성]했습니다. 자, 당신은 오직 FF에서 비표준'__proto__'을 사용할 수 있습니다 (unhijackable, 나는 생각합니다) – Bergi

+0

아주 좋아요, 나는 FF로도 납치 할 방법을 보지 못합니다! 나는 여전히 새로운 윈도우 객체 나 다른 메소드로부터 생성자를 얻으려는 @ Torsten의 제안이 브라우저 간 잡을 수없는 해법이 될 수있는 해결책이 될 수 있는지에 관심이있다. – Briguy37

1

예 ... 그냥했다 ...하지만 당신이 Array 때문에 잘 작동 new Array() ...

See example here

+2

죄송합니다, 그 테스트 케이스를 수행하지 않습니다. 편집 할 수 없습니다. – Briguy37

+0

@ Briguy37 그렇다면'[]'함수를 덮어 쓸 수 없습니다. 내부 생성자를 가리키고 있습니다 – ManseUK

+0

그럴 수도 있습니다. 그러나'Array' 프로토 타입을 수정하여 하이재킹하기 전에 함수를 추가하면'[] '로 생성 된 객체에서이 함수를 사용할 수 있습니다. 따라서 Array가 납치 된 후에이 작업을 수행 할 수있는 방법이 있는지 궁금합니다. – Briguy37

3

를 사용하는 경우는 [].constructor에 반드시 동일하지 않습니다 ... []를 사용하여 배열을 생성 [].constructor을 사용하면 원래의 배열 함수를 참조 할 수 있습니다.이 배열은 하드 와이어되어 있으므로 Array = function(){}에서 변경하지 않습니다.

Array = function() { alert("foo")}; 

// this will always point to the original Array 
[].constructor.prototype.foo = "bar"; 

var myArray = [0, 1]; 
alert(myArray.foo) // alerts "bar" 

http://jsfiddle.net/yXPJ8/5/

+0

첫 번째 해결책은 D.B. 행복한 :) (두 번째 것이 그의 첫 번째 요구 사항을 위반할 것입니다.) – Briguy37

+0

좋아요, "다른 어떤 것보다 먼저"비트를 놓쳤습니다. ;) –

+0

'arrayProto.constructor = wrongArray' 인 경우 어떻게됩니까? – Bergi

관련 문제