array length 가 업데이트 안됩니다.


#1

안녕하세요. Array length 에 관해서 궁금한게 생겨서 질문을 올립니다.
new 를 사용해서 3 사이즈의 Array 를 만들었습니다. 이후에 새로 키를 할당해서 값을 넣어주었습니다.
예를들어 다음과같은 코드입니다.

var arr3 = new Array(‘Minsu’, ‘Younghee’, ‘Jaejun’);
arr3[‘newkey’] = ‘Gogun’;
arr3[‘mini’] = ‘ka’;

이 경우 arr3.length 값이 여전히 3 이던데요. 왜 이렇게 되는지 알수 있을까요?
동적 할당(? 정확한 용어는 모르겠습니다)을 할 경우 length 값을 업데이트 안해줘서 그런걸까요?
이런 경우가 있기에 push 메소드를 써야한다면 동적할당은 어떤 경우에 유용할지 조언 부탁합니다.


(서재원) #2
  1. 배열은 객체입니다.
  2. js에는 정적 할당이라 할 만한 게 없습니다(전부 런타임에 만들어집니다. - 최적화를 한다면야 정적 할당을 끼어넣을 부분이 있긴 합니다만 언어 명세에서는 전부 런타임 시멘틱으로 기술하고 있습니다.).
  3. 배열 객체의 length 프로퍼티의 값은 이름이 숫자인 프로퍼티가 들어왔을 때에, 들어온 이름을 숫자로 바꾼 것을 기존의 length 프로퍼티의 값과 비교한 뒤 필요에 따라 수정됩니다.
  4. 배열의 요소(element)가 아닌 걸 정의할 때 유용하지요.

(Bugtype) #3

우리가 흔히 C++, java 등에 있는 array하고는 다릅니다.
c++, java 등에서 사용되는 array는 연속된 메모리주소에 있는 값을 말합니다.

int[] a = new int[]{0,1,2,3,4,5};
(메모리주소) (값) (값) (값) (값) ...
00400400 00 01 02 03 04 05 ...

하지만, javascript에서 array는 객체입니다.
연속된 메모리를 가지는 것은 아닙니다.
그리고 객체는 Property를 가질 수 있습니다.

var john = []; // john이라는 배열이라는 객체 생성.
john[“name”] = “john” // 객체는 속성을 가질 수 있음.

그러므로 john[“name”] = “john” 이 작동 되는 것입니다.

알아두셔야 할 것은…
javascript에서 array는

  1. Map이다. ( 즉 연속된 메모리 공간에 저장하는 것이 아닙니다. )
  • a[0]=1 a[99]=1 해도 정상작동.
  1. 객체다.
  2. 객체 이기 때문에 속성(Property)을 가질 수 있다.
  • 더 정확히 말하면 javascript에서 모든 type은 prototype을 가집니다.
  1. 요소(element)의 수를 세는 것이 아니라 제일 큰 index를 출력 합니다.
  • a[0]=1 a[99]=1 a.length하면 100 출력

(서재원) #4
  1. 모든 배열이 무조건적으로 Map 인건 아닙니다.
    Map으로서 굴러가는 건 구현체가 결정해야 하는 사항이기 때문에 실제로 어떻다~ 라고 이야기하기 매우 힘들 뿐더러, 말씀하신 거에 대한 반증으로, V8에서는 몇몇 특수한 상황에서 배열을 선형적인 메모리 구조를 갖게 만들어 줍니다.
  2. 모든 type은 prototype을 가진다? 아닙니다. primitive(scala) type들의 값들은 prototype을 가지지 않습니다.
    (혹여나 property를 의미하신 거라 하셔도 아니라고 말씀드리겠습니다. primitive type의 값들은 property 또한 가질 수 없습니다., 래퍼 객체를 생각하시고 하신 말씀이시라면, 래퍼 객체의 내부에는 여전히 primitive type의 값이 [[SymbolData]], [[BooleanData]] 와 같은 이름의 internal slot에 들어있는 걸 알아 주셨으면 합니다.)
  3. 제일 큰 index가 아닙니다. 오히려 ‘요소의 수’ 라고 하는 게 더 적절하며, 정확한 정의는 ‘모든 slot의 수’ 입니다(empty slot이라는 개념이 있습니다.).

(Bugtype) #5

잘못된 내용에 대한 지적을 해주셔서 감사드립니다.!

http://speakingjs.com/es5/ch18.html 에 의하면

The basic function of the length property is to track the highest index in an array
Thus, length does not count the number of elements, so you’d have to write your own function for doing so.

이라고 써져 있는데 여기서는 요소의 수를 세지 않고 제일큰 index로 되어 있습니다.
제가 잘못 이해한거 인지?? 설명 좀 부탁드릴 수 있을까요? : )


(서재원) #6

앞서 언급된 length에 대한 설명들을 정확도에 따라 나열하자면 다음과 같습니다:

제일 큰 index > 요소의 수 > 모든 slot의 수

“제일 큰 index” 라고 설명하는 것이 잘못된 이유:

  1. [1] 이라는 배열이 있을 때, 이 배열에서 최대 인덱스는 0 입니다.
    하지만 legnth1 이지요.
  2. [,,] 이라는 요소가 없는 배열이 있을 때, 이 배열에서 최대 인덱스는 없습니다.
    하지만 이 배열의 length3 이지요.

'요소의 수’라고 설명하는 것이 잘못된 이유.

  1. empty slot은 배열의 요소가 아닙니다(애초에, 어떤 값 이 아닙니다. 그래서 map과 같은 함수들로 mapping 할 때에도 무시되지요.). 그럼에도 불구하고 empty slotlength 프로퍼티에 영향을 미칩니다.

PS: 공유해주신 글에서 말하고자 하는 건, “length가 배열에서 가장 큰 인덱스를 구할 때 사용된다” 인 것 같습니다. 여담이지만 to track이나 length doesn't count the number of elements 같은 어휘를 보아 작성하신 분도 empty slot에 대해 알고 계신 것 같습니다.