2016-10-05 11 views
1

Тестируем новый Proxy objects, я удивлен, что, когда прокси-сервер установлен ключ автоматически преобразуется в строку:индекс прокси преобразуется в строку

var arr = ['a', 'b', 'c']; 

arr = new Proxy(arr, { 
    get: (original, key) => { 
    alert(typeof key); 
    return original[key]; 
    } 
}); 

arr[1]; // expected an alert with 'number'; got 'string' instead 

Там я ожидал бы, что typeof key будет number, потому что я передаю ему номер. Тем не менее, он преобразуется в строку внутри Proxy как-то, а фактический предупреждаемый тип - string. Вы можете указать see a small JSFiddle here, что демонстрирует проблему. arr все еще является массивом даже после прохождения через прокси.

Итак, Как я могу отличить от передачи строки и числа? я мог бы просто REGEX его, как в /\d+/.test(key), однако он не хотел проводить различие между этими ситуациями и он просто чувствует, как взломать:

arr['1']; 
arr[1]; 
+1

Идентификатор свойства преобразуется в строку еще до того, как будет определено значение доступа к ресурсу, то есть нет способа, чтобы прокси-объект знал, что такое исходное значение. См. Спецификацию: http://www.ecma-international.org/ecma-262/7.0/#sec-property-accessors-runtime-semantics-evaluation –

+0

По совпадению, собственный массив не будет различать 'arr ['1' ] 'и' arr [1] 'тоже по той причине, что объясняется в ответе. Поэтому да, '/^\ d + $ /' следует использовать. См. Http://stackoverflow.com/a/39802685/3731501 для примера. – estus

ответ

2

ключи свойств могут быть только строки или символы. Если вы используете что-то другое, например число, оно всегда сначала преобразуется в строку. Таким образом, при использовании прокси-сервера вы не можете различить эти две операции:

arr['1']; 
arr[1]; 

Оба они будут вызывать прокси получить обработчик с '1' в качестве ключа свойства.


Кроме того, тот факт, что вы используете массив ничего не меняет, он работает так же с массивами (которые особый вид объектов), как это работает с простыми объектами.


См. Также The Object Type in the specification.

+0

spec: http://www.ecma-international.org/ecma-262/6.0/#sec-object-type – birdspider

+0

Отлично, спасибо. С вашим первым предложением я также нашел более актуальную информацию: http://stackoverflow.com/questions/2940424/valid-javascript-object-property-names#comment32771282_2940427 (и ссылка на MDN: https: //developer.mozilla. org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects # Objects_and_properties). Таким образом, в основном это доступ к самому массиву, который преобразует его в строку, не связанную с прокси. –

+0

Стоит отметить, что я решил его с помощью простого 'if (key in lists) return lists [key];', который будет захватывать как общие методы массива, такие как '.forEach()', '.map()' и т. Д. а также упомянутые числовые индексы –