2011-10-17 4 views
2

이 코드는 어떻게 작동합니까?배열을 속성 이름으로 사용하려면 어떻게해야합니까?

if (!(args in pad)) { 
    pad[args] = self.apply(obj, arguments); 
} 

args는 배열이지만 JS 객체의 키이기 때문에 문자열이 아니어야합니까? 수표는 어떻게 작동합니까? array in object?

전체 맥락 here :

Function.prototype.memoize = function() { 
    var pad = {}; 
    var self = this; 
    var obj = arguments.length > 0 ? arguments[i] : null; 

    var memoizedFn = function() { 
     // Copy the arguments object into an array: allows it to be used as 
     // a cache key. 
     var args = []; 
     for (var i = 0; i < arguments.length; i++) { 
      args[i] = arguments[i]; 
     } 

     // Evaluate the memoized function if it hasn't been evaluated with 
     // these arguments before. 
     if (!(args in pad)) { 
      pad[args] = self.apply(obj, arguments); 
     } 

     return pad[args]; 
    } 

    memoizedFn.unmemoize = function() { 
     return self; 
    } 

    return memoizedFn; 
} 

답변

4

인수 배열하는 수단을 문자열로 변환 :

[1,2,3].toString() == "1,2,3"; //true 

in에서 사용할 때 자동으로 문자열로 변환 :

([1,2,3] in ({"1,2,3":""})) //true 

in perator는 왼쪽에있는 문자열 만 허용합니다.

를 사용하면 개체 키가 문자열 일 수 있기 때문에 동일한 변환이 다시 발생합니다. 예를 들어, array[1]을 사용하는 경우 숫자는 문자열로 변환되기 때문에 실제로는 array["1"]입니다.

+0

하지만 어디에서 주조하나요? JS 인터프리터는 기본적으로 pads [args]를 사용할 때 기본적으로 모든 args 유형을 string으로 변환하려고 시도합니까? – DrStrangeLove

+0

고마워요 !! 이 줄을 설명해주십시오 : var obj = arguments.length> 0? arguments [i] : null; 나는 무엇을 참조합니까? 루프가 없습니다. – DrStrangeLove

+0

즉,'arguments.length> 0' 일 때 함수가 작동하지 않습니다. 왜냐하면'i'는 스코프에서 알려진 변수가 아니므로'ReferenceError'를 던질 것이기 때문입니다. 이 기능이 작동한다면 더 나쁠 것입니다;) – Esailija

3

이 일을 정리해야

입니다
var a = [1,2,3] 
var s = "" + a 
var x = {} 
x[a] = "hello world" 
alert(s in x) 

, 속성 이름이 항상 문자열과을 필요에 따라 을 변환됩니다. ("베어"객체는 일반적으로 적절한 문자열 지정이 없기 때문에 일반적으로 속성 이름으로 작동하지 않습니다. 그러나 toString/valueOf을 사용할 수있는 방법은 아래 참조)

ECMAScript 5th Edition Specification은 "단순한"것들을 찾기에는 정말로 털이 있습니다. 이것은 내가 아는 가장 복잡한 말로 표현 된 언어 사양이지만 속성 이름을 수식으로 받아들이는 다양한 프로덕션으로 이어집니다.

11.2.1 항 참조 : 부동산의 접근 자

생산 MemberExpression 다음과 같이 MemberExpression [표현식] 평가 :

[...] 6. propertyNameString이 ToString하자 (propertyNameValue). [...] 제 리턴 값 [...]를 참조 이름이 [...]

절 11.8.7을 propertyNameString 된다 : 오퍼레이터에

ShiftExpression의 RelationalExpression : RelationalExpression [aka propertyNameValue]은 다음과 같이 평가됩니다.

[...] 6.인수가 ToString (lval [일명 propertyNameValue]) 인 rval의 [[HasProperty]] 내부 메소드를 호출 한 결과를 반환합니다.

이제 다음 체인 (모든 작은 세부 사항에 대한 사양을 참조하십시오) ToString(propertyNameValue)의 결과를 결정하기 위해 발생

  1. ToString, 섹션 9.8
  2. ToPrimitive, 9.1
  3. (개체의 경우) [[DefaultValue]] ("문자열"힌트 사용), 섹션 8.12.8
  4. (개체의 경우)의 결과또는 valueOf() (제 1 호출 한)

이 동일한 ToString 프로세스 의 속성에 대한 모든 액세스를 적용 - 그것을 할 obj[prop] 또는 obj.HasOwnProperty(prop) 또는 prop in obj.

해피 코딩.

+0

또는 http://jsfiddle.net/eKZhp/ –

+1

또는 (업데이트 됨) : http://jsfiddle.net/eKZhp/1/ –

+0

@Jared Farrish 고마워 :-) –

관련 문제