알고리즘은 풀던 중 string.charAt(x)
과 string[x]
은 어떻게 다른가에 대해 고민하다.
위 두 글을 보고 charAt과 string[]의 작동법에 대해 찾아보게 되었다.
그 후 1번째 글에서 봤던 아래 코드 결과가 나온 과정을 정리해보기로 했다.
'hello'[NaN]
'hello'.charAt(NaN)
15.5.5.2 [GetOwnProperty] # Ⓣ Ⓔ
String objects use a variation of the [[GetOwnProperty]] internal method used for other native ECMAScript objects (8.12.1). This special internal method is used to add access for named properties corresponding to individual characters of String objects.
Assume S is a String object and P is a String.
When the [[GetOwnProperty]] internal method of S is called with property name P, the following steps are taken:
Let desc be the result of calling the default [[GetOwnProperty]] internal method (8.12.1) on S with argument P.
If desc is not undefined
return desc.
If ToString(abs(ToInteger(P)))
is not the same value as P, return undefined
.
Let str be the String value of the [[PrimitiveValue]] internal property of S.
Let index be ToInteger(P).
Let len be the number of characters in str.
If len ≤ index, return undefined.
Let resultStr be a String of length 1, containing one character from str, specifically the character at position index, where the first (leftmost) character in str is considered to be at position 0, the next one at position 1, and so on.
Return a Property Descriptor { [[Value]]: resultStr, [[Enumerable]]: true, [[Writable]]: false, [[Configurable]]: false }
15.5.4.4 String.prototype.charAt (pos) # Ⓣ Ⓡ
Returns a String containing the character at position pos in the String resulting from converting this object to a String. If there is no character at that position, the result is the empty String. The result is a String value, not a String object.
If pos is a value of Number type that is an integer, then the result of x.charAt( pos) is equal to the result of x.substring( pos, pos+1).
When the charAt method is called with one argument pos, the following steps are taken:
Call CheckObjectCoercible
passing the this value as its argument.
Let S be the result of calling ToString
, giving it the this value as its argument.
Let position be ToInteger(pos)
.
Let size be the number of characters in S.
If position < 0 or position ≥ size, return the empty String.
Return a String of length 1, containing one character from S, namely the character at position position, where the first (leftmost) character in S is considered to be at position 0, the next one at position 1, and so on.
NOTE The charAt function is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.
'hello'[NaN]
'hello'.charAt(NaN)
위 string의 []
스펙 15.5.5.2 [GetOwnProperty]의 3번을 그럼 확인해 보면 될 것이다.
If ToString(abs(ToInteger(P))) is not the same value as P, return undefined.
위 3번 내용은 다시 아래 내용으로 분리해서 생각해보자.
ToInteger
스펙
The abstract operation ToInteger converts its argument to an integral numeric value. This abstract operation functions as follows:
Let number be the result of calling ToNumber
on the input argument.
If number is NaN
, return +0.
If number is +0, −0, +∞, or −∞, return number.
Return the result of computing sign(number) * floor(abs(number)).
∴ 3-1 결과 값 +0
Returns the absolute value of x; the result has the same magnitude as x but has positive sign.
3-1 의 값이 +0 이였기 때문에 그대로 +0 반환
∴ 3-2 결과 값 +0
type 이 number이니 Number 에서 보라고 하는 9.8.1을 확인해보면
9.8.1-2번에서 +0 은 "0"로 변환됨을 확인할 수 있다.
∴ 3-3 결과 값 '0'
드디어 비교하기
'0' 과 NaN 의 값은 같은가? -> false
undefined
스펙의 2번부터 확인해보자
2. Let S be the result of calling ToString, giving it the this value as its argument.
'hello'은 이미 type String 임으로
∴ S = 'hello'
The abstract operation ToInteger converts its argument to an integral numeric value. This abstract operation functions as follows:
Let number be the result of calling ToNumber
on the input argument.
If number is NaN
, return +0.
If number is +0, −0, +∞, or −∞, return number.
Return the result of computing sign(number) * floor(abs(number)).
3. Let position be ToInteger(pos).
3에서 ToInteger을 호출
ToInteger(pos)의 1번에서 ToNumber를 호출
ToNumber 의 스펙을 보면 type이 number 이기 때문에
NaN -> NaN 반환
ToInteger(pos)의 2번에서 NaN
은 +0을 반환
NaN -> 0+ 반환
∴ position = 0+
Let size be the number of characters in S.
hello의 size 는 5
size = 5
5. If position < 0 or position ≥ size, return the empty String.
0 은 유효함으로 넘어감
6. Return a String of length 1, containing one character from S, namely the character at position position, where the first (leftmost) character in S is considered to be at position 0, the next one at position 1, and so on.
hello
의 0번째 문자는 'h'임으로
'h' 반환
아래의 코드도 생각해보기
'hello'[true]
'hello'.charAt(true)
console.log('hello'['a']) // console에 찍힐 값은?
'hello'['a'] = 'aaa'
console.log('hello'['a']) // console에 찍힐 값은?