2010-11-30 6 views
8

안전하게 문자열로 아무것도 변환하는? test.toString()을 호출하지 않고 typeof x == "string" 체크를 사용하지 않고 확인합니다. 비 문자열을 허용하고 싶습니다.어떻게 자바 스크립트

참고 : 콘텐츠 페이지의 js 범위에있는 개체를 다루는 FF 확장 프로그램입니다.

+2

당신은'toString()'호출하지 않고 반환 무엇을 기대합니까? – casablanca

+1

글쎄, 항상 JSON 시리얼 라이저가 있습니다 ... – cdhowie

+1

예제 구문을 수정했습니다. –

답변

5

JavaScript는 자체를 포함하여 을 포함하여 스크립트에 액세스 할 수있는 거의 모든 개체의 속성을 수정할 수 있습니다. 개체는 설명 된 방식으로 "악의적 인 코드"에 취약합니다.

만 프리미티브가 안전 보장, 그래서 유일한 방법은 "악의 코드가"실행되지 않습니다 있는지 확인하는 것은 같은 것을 할 것입니다 : 슬프게도

function safeToString(x) { 
    switch (typeof x) { 
    case 'object': 
     return 'object'; 
    case 'function': 
     return 'function'; 
    default: 
     return x + ''; 
    } 
} 
+0

[Lodash array] (https://lodash.com/)를 사용하여 더 세분화가 필요한 사람들 (예 :'[1,2,3]'에서'' '1,2,3 '' CSV로 변환하려는 경우) docs/4.17.4 # isArray)/[객체 감지] (https://lodash.com/docs/4.17.4#isObject)는 객체 케이스에 넣을 수 있습니다 : return _.isArray (x) &&! _. some (x, _.isObject)? _.toString (x) : 'object'; ' – jmmygoggle

5

(toString: function(){alert("evil code"); return "test";}) 여기에도 구문 분석을받지 못하면 구문 오류가 발생합니다. () 대신 {}을 사용하고 싶습니다.

""+test; 
""+2; // "2" 
""+4.5 // "4.5" 
""+[1, 2, 3] // "1,2,3" 
""+{} // '[object Object]' 

그러나 여기가 안전하게 개체를 변환하는 진짜 방법이 없다 :

는 일반적으로 당신은 캐스트를 수행하기 위해 빈 문자열 더하기 연산자를 사용할 수 있습니다.

delete test.toString을 사용하면 재정의 된 메서드를 제거 할 수 있습니다.이 메서드는 '[object Object]'을 반환하는 일반적인 toString 메서드로 되돌아갑니다. test.toString.toString()을 통해 toString 메서드 자체를 문자열로 변환 할 수도 있습니다.

"function() { alert("evil code"); return "test"; }" 

정확하게 여기에서 원하는 것은 사용자에게 달려 있습니다.

+1

이것은 "evil"toString을 암묵적으로 호출합니다. –

+0

@Matthew 실제로 여기 오전 5시 30 분이고 그의 예제 코드도 손상되어 업데이트됩니다. –

+0

답변을 업데이트하십시오. –

4

하나의 옵션은 다음과 같습니다

Object.prototype.toString.call(test) 

이 제공 : 시험의 경우

"[object Object]" 

. 기본적으로 타입 정보 만 제공합니다. 그러나 정확한 시나리오가 무엇인지 궁금합니다. 악의적 인 물체는 어떻게 페이지에로드됩니까? 그들이 페이지에서 임의의 코드를 실행할 수 있다면 기본적으로 운이 없다. 무엇보다도 Object.prototype.toString을 다시 정의 할 수 있습니다.

+1

'Object.prototype.toString'을 오버라이드 (override) 할 수 있기 (위해) 때문에, 이것도 절대 안전한 것은 아닙니다. – casablanca

+0

@casa, true. 이 기능은 실제로 자체적으로 포함 된 개체를 페이지에 전달하는 것만으로 도움이됩니다. 전역 속성을 수정할 수있는 경우 모든 베팅이 해제됩니다. –

+0

여기에 catch가 있습니다. 악의적 인 코드는 내 코드와 다른 범위에서 만들어집니다. 그것은 콘텐츠 페이지의 범위를 다루는 FF ext입니다. 따라서 해당 범위에서 오는 객체는 다른 Object.prototype을 가져야하므로'Object.prototype.toString'을 사용하는 것이 안전해야합니다. – erikvold

1

, @Matthew Flaschen의 (현재 가능) 대답 ES6/ES2015에서 Symbol 클래스와 함께 작동하지 않습니다

console.log("" + Symbol("foo")); 
// results in an exception: 
// `Uncaught TypeError: Cannot convert a Symbol value to a string` 
// (at least in Chrome as of this writing). 

https://jsfiddle.net/L8adq9y4/

(I는로, 왜 아무 생각이 없다 String() 기능은 String에 (적어도 내가 시도하는 사람에서) 어떤 값을 변환 할 수있을 것 같다 :은 완벽하게 좋은 toString() 방법 :

console.log(Symbol("foo").toString()); 

https://jsfiddle.net/v1rqfhru/

솔루션 그래도 거기에있다 . 당신이 String()에 좋아하는 무엇이든을 통과, 그래서

console.log(String("A String")); 
console.log(String(undefined)); 
console.log(String(null)); 
console.log(String({value: "An arbitrary object"})); 
console.log(String({toString: function(){return "An object with a toString() method";}})); 
console.log(String(function(){return "An arbitrary function"})); 

https://jsfiddle.net/6uc83tsc/

을 당신은 꽤 좋은 결과를 얻을 것이다 : 존재하는 경우에도 toString()를 호출합니다.

+0

"좋아하는 것을 String()으로 넘겨 주면 꽤 좋은 결과를 얻을 수 있습니다." 좀 빠지는. 'String ([Symbol ('AAAA')])'는 "Uncaught TypeError : 심볼 값을 문자열로 변환 할 수 없습니다"를 제공합니다. –

0

로다시 toString 메서드를 사용할 수 있습니다.

_.toString(null); 
// => '' 

_.toString(-0); 
// => '-0' 

_.toString([1, 2, 3]); 
// => '1,2,3' 

Link to documentation

관련 문제