2015-11-29 2 views
3
var a = "foo"; 
var c = Array.prototype.join.call(a, "-"); // 'f-o-o' 

Как работает вторая строка кода? Я не вижу никакого преобразования строки в массив и затем преобразования обратно, это происходит в фоновом режиме? Я столкнулся с таким кодом, и это очень странно, метод массива принимает строку.Что делает Array.prototype.join.call в фоновом режиме для строки?

+0

NB: методы массива, такие как splice(), reverse(), sort() и т. Д., Которые изменяют массив на месте, НЕ будут работать для строк, поскольку строки неизменяемы – Danield

ответ

4

Строки является массивом как объект, так как он имеет свойство length и вы можете получить доступ к его элементам (символы), используя [] как того, что вы можете применить большинство операций манипулирования массива на нем.

Function.prototype.call() вызывает данную функцию функции с использованием первого параметра, как this и течет одна как нормальная параметров.

От этого Array.prototype.join.call(a, "-") вызывается функция join на объекте a в вашем случае строка.

3

String - подобный массиву объект. Массивный объект обеспечивает индексированный доступ к элементам и длину свойства. Вы можете прочитать больше here

+0

Да, но строка не ведет себя как массив в смысл, что строки не изменяемы и массивы. Таким образом, можно ли использовать все методы безмасштабируемых массивов в строке? – daremkd

+0

Вы можете использовать изменяемые методы (push, sort, reverse ...), но строка не изменит ее значение. И, конечно же, вы можете использовать любые немыслимые методы –

+0

@daremkd: ... потому что 'str =" 123 "; str [0] = 'x'; console.log (str); 'показывает' 123', а не 'x23'. Даже 'str = новая строка (« 123 »); str [0] = 'x'; console.log (str); 'делает. Присвоение свойствам индексного стиля строки является no-op, эти свойства недоступны для записи. –

5

specification for Array.prototype.join(внизу). Он не требует, чтобы this работал над массивом, просто чтобы он имел length и свойства с именами, такими как 0, 1 и т. Д. Строки делают, и поэтому join может работать на строке.

Из спецификации:

Примечания 2 join функции преднамеренно родовой; он не требует, чтобы его значение this представляло собой объект Array. Поэтому он может быть передан другим типам объектов для использования в качестве метода.

Вот полный алгоритм из спецификации:

  1. Пусть O быть ToObject (это значение).
  2. ReturnIfAbrupt ( O).
  3. Пусть Len быть ToLength (Get ( O, "length")).
  4. ReturnIfAbrupt ( len).
  5. Если сепаратор является неопределенным , пусть сепаратор быть одним элементом Строка ",".
  6. Let sep be ToString ( separator).
  7. ReturnIfAbrupt ( sep).
  8. Если len равно нулю, верните пустую строку.
  9. Let element0 be Get ( O, "0").
  10. Если element0 является неопределенными или нуль, пусть R быть пустой строкой; в противном случае пусть R будет ToString ( элемент0).
  11. ReturnIfAbrupt ( R).
  12. Да k be 1.
  13. Повтор, в то время как к < Len
    1. Пусть S быть строковое значение получают путем конкатенации R и SEP.
    2. Пусть элемент быть Get ( O, ToString ( к)).
    3. Если элемента является неопределенными или нулем, пусть следующего быть пустой строкой; в противном случае пусть следующий be ToString ( элемент).
    4. ReturnIfAbrupt ( следующий).
    5. Пусть R быть строковым значением, получаемое конкатенацией S и следующего.
    6. Увеличение к на 1.
  14. Возвращение R.
+0

Это для всех методов неразрушающего массива? Например: https://gist.github.com/dare05/1feabb110d24676167b3 также может работать со строкой. Кажется, что в начале он выполняет внутреннюю .split ('') перед применением функции к каждой строке. – daremkd

+0

@daremkd: Большинство методов массива преднамеренно универсальны. Многие методы на других встроенных прототипах тоже. Если вы ищете спецификацию для «намеренно генерических» (они очень согласуются с их формулировкой на этом :-)), вы найдете * пучок * (включая 'Array.prototype.map'). –

+0

@daremkd: См. Также раздел «объекты, подобные массиву» [этот ответ] (http://stackoverflow.com/questions/9329446/for-each-over-an-array-in-javascript/9329476#9329476) , –

Смежные вопросы