인덱스는 0부터 시작하기 때문에 index로 들어갈 수 있는 가장 큰 수는 (문자열.legnth-1)이다. 존재하지 않는 index를 인자로 전달하면 공백이 출력됩니다.
charAt는 index에 해당하는 문자를 리턴하고,chartCodeAt은 유니코드 값을 리턴하는 차이가 있다.
예제 코드
JAVASCRIPT
charAt(index)
charCodeAt()
charCodeAt메서드는 index에 해당하는 문자의 unicode 값을 리턴합니다.
문법(Syntax)
JAVASCRIPT
string.charCodeAt(index)
Copy
인자
ndex - 필수
0보다 큰 정수
설명(description)
유니코드는 모든 시스템에서 일관되게 문자를 표현하기 위한 산업표준입니다.
charCodeAt은 주어진 index에 해당하는 유니코드 값을 리턴하는데 이 값은 unicode가 지원되는 모든 시스템에서 동일한 문자를 가르킵니다.
charAt는 index에 해당하는 문자를 리턴하고,chartCodeAt은 유니코드 값을 리턴하는 차이가 있습니다.
예제 코드
JAVASCRIPT
var stringName ='자바스크립트';console.log(stringName.charCodeAt(0));// 51088// http://www.unicode.org/charts/PDF/UAC00.pdf 에서 '자'을 찾아보면 'C790'인데 이것은 16진수다.// 이를 10진수로 변환하면 51088 된다.
var obj = { foo: function() {}, bar: function() {} };
ES6에서는 아래와 같이 줄일 수 있습니다.
var obj = { foo() {}, bar() {} };
정적 메소드(static methods)
static 메소드는 클래스의 인스턴스 (var a = new testFunc()) 필요없이 호출 가능합니다. 또한 클래스의 인스턴스에서 static 메소드를 호출 할 수 없습니다.
class Point { constructor(x, y) { this.x = x; this.y = y; } static distance(a, b) { const dx = a.x - b.x; const dy = a.y - b.y; return Math.sqrt(dx*dx + dy*dy); } } const p1 = new Point(5, 5); const p2 = new Point(10, 10); console.log(Point.distance(p1, p2)); var p3 = new Point(1, 1); p3.distance(p1, p2);
class의 static 메소드
인스턴스 없이 정상적으로 distance가 호출 되는 것과, 인스턴스를 통해 distance를 호출 할 때 TypeError가 발생하는 것을 확인 할 수 있습니다.
오토박싱(Autoboxing)
autoboxing이란?
일반 함수에서 this는 window 객체를 가르키게 됩니다. this가 window 객체 (global object)를 가르키는 이유는 autoboxing 덕분입니다.
non-strict 모드에서 ([자바스크립트] this의 정체참고) this 값이 null 혹은 undefined 일 경우 window 객체(global object)로 자동으로 변환해 주는 것을 autoboxing이라고 합니다.
프로토타입 기반의 클래스에서 autoboxing
프로토타입 기반의 class의 경우
function Animal() { } Animal.prototype.speak = function(){ console.log(this); return this; } Animal.eat = function() { console.log(this); return this; } let obj = new Animal(); let speak = obj.speak; speak(); // global object let eat = Animal.eat; eat(); // global object
프로토타입 기반의 클래스의 autoboxing
autoboxing이 되어, 일반 함수를 호출하는 것처럼 메소드를 호출 한 경우 window 객체(global object)를 출력하는 것을 확인 할 수 있습니다.
ES6의 클래스 기반의 autoboxing
ES6의 class에서는 autoboxing이 되지 않습니다.
class Animal { speak() { console.log(this); return this; } static eat() { console.log(this); return this; } } let obj = new Animal(); let speak = obj.speak; speak(); // undefined obj.speak(); let eat = Animal.eat; eat(); // undefined Animal.eat();
ES6의 class는 autoboxing이 안됨
autoboxing이 되지 않아, 일반 함수를 호출하는 것처럼 메소드를 호출 한 경우 undefined가 출력되는 것을 확인 할 수 있습니다.
그렇기 때문에 ES6의 클래스에서 메소드를 변수에 저장하여 사용할 경우, this에 유의해서 사용해야 합니다.
3. 클래스 상속(sub classing)
ES6의 클래스 상속
extends 키워드를 통하여 클래스를 상속 받아, 자식 클래스를 만들 수 있습니다.
class Animal { constructor(name) { this.name = name; } speak() { console.log(this.name + ' makes a noise.'); } } class Dog extends Animal { speak() { console.log(this.name + ' barks.'); } } var d = new Dog('Mitzie'); d.speak();
ES6의 클래스 상속
프로토타입 기반의 클래스 상속
프로토타입 기반의 클래스도 extends 키워드를 통해 상속 할 수 있습니다.
function Animal (name) { this.name = name; } Animal.prototype.speak = function () { console.log(this.name + ' makes a noise.'); } class Dog extends Animal { speak() { console.log(this.name + ' barks.'); } } var d = new Dog('Mitzie'); d.speak();
프로토타입 기반의 클래스 상속
일반 객체의 클래스 상속
일반 객체는 extends 키워드를 통해 상속할 수 없습니다. 상속하고 싶다면 Object.setPrototypeOf 메소드를 사용하여 상속해야 합니다.
var Animal = { speak() { console.log(this.name + ' makes a noise.'); } }; class Dog { constructor(name) { this.name = name; } speak() { console.log(this.name + ' barks.'); } } Object.setPrototypeOf(Dog.prototype, Animal); var d = new Dog('Mitzie'); d.speak();
일반 객체의 클래스 상속
4. Species
class MyArray extends Array { // 부모 Array 생성자로 종류 덮어쓰기 static get [Symbol.species]() { return Array; } } var a = new MyArray(1,2,3); var mapped = a.map(x => x * x); console.log(mapped instanceof MyArray); // false console.log(mapped instanceof Array); // true
Symbol.species
Array를 상속받은 MyArray에서 Array의 default 생성자를 덮어 쓰고 싶을 경우, Symbol.species를 사용하면 됩니다. (get []의 문법은 [자바스크립트] getter, setter참고 바랍니다.)
Symbol.species로 Array의 생성자를 가져오고, get [] 로 Array를 리턴함으로 부모 Array의 생성자를 덮어 쓸 수 있습니다.
5. super로 부모 클래스 호출하기
super 키워드를 홈하여 부모 클래스의 메소드를 호출 할 수 있습니다.
프로토타입 기반의 부모 클래스 메소드 호출
function Cat(name) { this.name = name; } Cat.prototype.speak = function () { console.log(this.name + ' makes a noise.'); }; function Lion(name) { // `super()` 호출 Cat.call(this, name); } // `Cat` 클래스 상속 Lion.prototype = new Cat(); Lion.prototype.constructor = Lion; // `speak()` 메서드 오버라이드 Lion.prototype.speak = function () { Cat.prototype.speak.call(this); console.log(this.name + ' roars.'); }; var lion = new Lion("BIG"); lion.speak();
indexAn integer between0andstr.length - 1. If theindexcannot be converted to the integer or noindexis provided, the default is0, so the first character ofstris returned.
Characters in a string are indexed from left to right. The index of the first character is0, and the index of the last character—in a string calledstringName—isstringName.length - 1. If theindexyou supply is out of this range, JavaScript returns an empty string.
If noindexis provided tocharAt(), the default is0.
The following example displays characters at different locations in the string "Brave new world":
var anyString = 'Brave new world';
console.log("The character at index 0 is '" + anyString.charAt() + "'");
// No index was provided, used 0 as default
console.log("The character at index 0 is '" + anyString.charAt(0) + "'");
console.log("The character at index 1 is '" + anyString.charAt(1) + "'");
console.log("The character at index 2 is '" + anyString.charAt(2) + "'");
console.log("The character at index 3 is '" + anyString.charAt(3) + "'");
console.log("The character at index 4 is '" + anyString.charAt(4) + "'");
console.log("The character at index 999 is '" + anyString.charAt(999) + "'");
These lines display the following:
The character at index 0 is 'B'
The character at index 0 is 'B'
The character at index 1 is 'r'
The character at index 2 is 'a'
The character at index 3 is 'v'
The character at index 4 is 'e'
The character at index 999 is ''
The following provides a means of ensuring that going through a string loop always provides a whole character, even if the string contains characters that are not in the Basic Multi-lingual Plane.
var str = 'A \uD87E\uDC04 Z'; // We could also use a non-BMP character directly
for (var i = 0, chr; i < str.length; i++) {
if ((chr = getWholeChar(str, i)) === false) {
continue;
}
// Adapt this line at the top of each loop, passing in the whole string and
// the current iteration and returning a variable to represent the
// individual character
console.log(chr);
}
function getWholeChar(str, i) {
var code = str.charCodeAt(i);
if (Number.isNaN(code)) {
return ''; // Position not found
}
if (code < 0xD800 || code > 0xDFFF) {
return str.charAt(i);
}
// High surrogate (could change last hex to 0xDB7F to treat high private
// surrogates as single characters)
if (0xD800 <= code && code <= 0xDBFF) {
if (str.length <= (i + 1)) {
throw 'High surrogate without following low surrogate';
}
var next = str.charCodeAt(i + 1);
if (0xDC00 > next || next > 0xDFFF) {
throw 'High surrogate without following low surrogate';
}
return str.charAt(i) + str.charAt(i + 1);
}
// Low surrogate (0xDC00 <= code && code <= 0xDFFF)
if (i === 0) {
throw 'Low surrogate without preceding high surrogate';
}
var prev = str.charCodeAt(i - 1);
// (could change last hex to 0xDB7F to treat high private
// surrogates as single characters)
if (0xD800 > prev || prev > 0xDBFF) {
throw 'Low surrogate without preceding high surrogate';
}
// We can pass over low surrogates now as the second component
// in a pair which we have already processed
return false;
}
In an ECMAScript 2016 environment which allows destructured assignment, the following is a more succinct and somewhat more flexible alternative in that it does increment for an incrementing variable automatically (if the character warrants it in being a surrogate pair).
let str = 'A\uD87E\uDC04Z' // We could also use a non-BMP character directly
for (let i = 0, chr; i < str.length; i++) {
[chr, i] = getWholeCharAndI(str, i)
// Adapt this line at the top of each loop, passing in the whole string and
// the current iteration and returning an array with the individual character
// and 'i' value (only changed if a surrogate pair)
console.log(chr)
}
function getWholeCharAndI(str, i) {
let code = str.charCodeAt(i)
if (Number.isNaN(code)) {
return '' // Position not found
}
if (code < 0xD800 || code > 0xDFFF) {
return [str.charAt(i), i] // Normal character, keeping 'i' the same
}
// High surrogate (could change last hex to 0xDB7F to treat high private
// surrogates as single characters)
if (0xD800 <= code && code <= 0xDBFF) {
if (str.length <= (i + 1)) {
throw 'High surrogate without following low surrogate'
}
let next = str.charCodeAt(i + 1)
if (0xDC00 > next || next > 0xDFFF) {
throw 'High surrogate without following low surrogate'
}
return [str.charAt(i) + str.charAt(i + 1), i + 1]
}
// Low surrogate (0xDC00 <= code && code <= 0xDFFF)
if (i === 0) {
throw 'Low surrogate without preceding high surrogate'
}
let prev = str.charCodeAt(i - 1)
// (could change last hex to 0xDB7F to treat high private surrogates
// as single characters)
if (0xD800 > prev || prev > 0xDBFF) {
throw 'Low surrogate without preceding high surrogate'
}
// Return the next character instead (and increment)
return [str.charAt(i + 1), i + 1]
}
While the previous example may be more useful for programs that must support non-BMP characters (since it does not require the caller to know where any non-BMP character might appear), in the event that onedoeswish, in choosing a character by index, to treat the surrogate pairs within a string as the single characters they represent, one can use the following:
function fixedCharAt(str, idx) {
let ret = ''
str += ''
let end = str.length
let surrogatePairs = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g
while ((surrogatePairs.exec(str)) != null) {
let lastIdx = surrogatePairs.lastIndex
if (lastIdx - 2 < idx) {
idx++
} else {
break
}
}
if (idx >= end || idx < 0) {
return ''
}
ret += str.charAt(idx)
if (/[\uD800-\uDBFF]/.test(ret) && /[\uDC00-\uDFFF]/.test(str.charAt(idx + 1))) {
// Go one further, since one of the "characters" is part of a surrogate pair
ret += str.charAt(idx + 1)
}
return ret
}