자주 사용한 것 *
표기
엄격모드를 지원하지 않는 브라우저에서는 엄격 모드의 코드가 다른 방식으로 동작하며,
엄격 모드의 코드와 비-엄격 모드의 코드는 공존할 수 있음.
// 문서 최상단 - 전체 영역에 모드 적용
‘ues strict’
function strict() {
// 함수-레벨 strict mode 문법
'use strict';
function nested() { return "And so am I!"; }
return "Hi! I'm a strict mode function! " + nested();
}
function notStrict() { return "I'm not strict."; }
// ===== 1. 글로벌 변수 생성 방지
mistypedVaraible = 17; // error
// ===== 2. 글로벌 변수 생성 방지
// 쓸 수 없는 프로퍼티에 할당
var undefined = 5; // TypeError 발생
var Infinity = 5; // TypeError 발생
// 쓸 수 없는 프로퍼티에 할당
var obj1 = {};
Object.defineProperty(obj1, "x", { value: 42, writable: false });
obj1.x = 9; // TypeError 발생
// getter-only 프로퍼티에 할당
var obj2 = { get x() { return 17; } };
obj2.x = 5; // TypeError 발생
// 확장 불가 객체에 새 프로퍼티 할당
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = "ohai"; // TypeError 발생
// ===== 3. 삭제할 수 없는 프로퍼티를 삭제시 예외 발생
delete Object.prototype; // TypeError 발생
// ===== 4. 객체의 모든 프로퍼티 중복 불가
var o = { p: 1, p: 2 }; // !!! 구문 에러
// ===== 5. 고유한 함수 파라미터 이름
function sum(a, a, c){ // !!! 구문 에러
"use strict";
return a + b + c; // 코드가 실행되면 잘못된 것임
}
// ===== 6. 8진 구문을 금지
delete Object.prototype; // TypeError 발생
// ===== 7. primitive 값에 프로퍼티를 설정하는 것을 금지
(function() {
"use strict";
false.true = ""; // TypeError
(14).sailing = "home"; // TypeError
"with".you = "far away"; // TypeError
})();
var list = [1, 2, 3]
var result
console.log(Array.isArray(list)) // true
list.forEach(function (value, index){
console.log(value, index) // 1, 0 / 2, 1 / 3, 2
})
// ==========================================
result = list.map(function (a){
return a * 2
})
console.log(result) // [2, 4, 6] / result !== list
// ==========================================
result = list.filter(function (value, index){
return index === 0 || value === 3
})
console.log(result) // [1, 3] / result !== list
// ==========================================
result = list.reduce(function (total, currentValue){
console.log(currentValue) // 1 / 2 / 3
return total + currentValue
})
console.log(result) // 6
result = list.reduce(function (acc, value){
acc.base += value
acc.multi += value * 2
return acc
}, {base: 0, multi: 0})
console.log(result) // {base: 6, multi: 12} / result !== list
// reduceRight - index 내림차순으로 진행
// ==========================================
result = list.every(function (a){
return a > 1
})
console.log(result) // false / 모든 entry가 조건 충족시. true
// ==========================================
result = list.some(function (a){
return a > 2
})
console.log(result) // true / 일부 entry가 조건 충족시. true
// ==========================================
console.log(list.indexOf(2)) // 2 / 앞에서 첫번째 entry의 index
// lastIndexOf - 뒤에서 첫번째 entry의 index 반환
JSON 직렬화 / 객체화
console.log(JSON.parse('{"a":"1","b":"2"}')) // {a:1, b:2}
console.log(JSON.stringify({a:1, b:2})) // '{"a":"1","b":"2"}'
var date1 = new Date().now() // 현재 일시
var date2 = new Date().valueOf() // ms 값으로 반환
// 전역 객체에 생성하지 않음
var x = 'global';
let y = 'global';
console.log(this.x); // "global"
console.log(this.y); // undefined
// 블록 기준으로 스코프가 제한
let x = 1
if (x === 1) {
let x = 2
console.log(x) // 2
}
console.log(x) // 1
// cosnt 초기화 이후 변경 불가
let a = 1
const b = 2
a = 3 // OK
b = 4 // error
let a = [{key1: 11, key2: 22}, {key1: 33, key2: 44}]
for(const item of a){
console.log(item.key1, item.key2)
// 11, 22
// 33, 44
}
function test(a, b = 10){
console.log(a * b)
}
test(5) // 50
function rest(a, ...b){
console.log(a, b)
}
rest(1, 2, 3, 4) // 1, [2, 3, 4]
let a = [1, 3]
let b = [2, 4]
const spred = [...a, ...b]
console.log(spred) // [1, 3, 2, 4]
let [a, b, ...rest] = [10, 20, 30, 40, 50]
console.log(a, b, rest) // 10, 20, [30, 40, 50]
let { a, b } = { a: 10, b: 20 }
console.log(a, b) // 10, 20
console.log(`string text line 1
string text line 2`)
// "string text line 1
// string text line 2"
var a = 1;
console.log(`${a} * 2 = ${a * 2}`)
단순히 function 을 => 가 대체하는게 아님.
this나 super에 대한 바인딩이 되지 않는게 큰 차이, 이외에 기능적 차이점 존재
const func1 = (a, b) => {
console.log(a, b)
}
func1(1, 2) // 1, 2
const func2 = (a, b) => a * b
console.log(func2(5, 2)) // 10
비동기 처리를 위한 기능
let schrodingerBox = new Promise((resolve, reject) => {
let rand = Math.round(Math.random())
setTimeout(() => {
if(rand){
resolve('야옹')
} else {
reject('...')
}
}, 250)
})
schrodingerBox.then((success) => {
console.log('성공', success)
}, (fail) => {
console.log('실패', fail)
})
// 성공시 resolve, 실패시 reject (에러) 반환
객체를 생성하기 위한 템플릿
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
static displayName = "Point";
static distance(a, b) {
const dx = a.x - b.x;
const dy = a.y - b.y;
return Math.hypot(dx, dy);
}
}
const p1 = new Point(5, 5);
const p2 = new Point(10, 10);
p1.displayName; // undefined
p1.distance; // undefined
p2.displayName; // undefined
p2.distance; // undefined
console.log(Point.displayName); // "Point"
console.log(Point.distance(p1, p2)); // 7.0710678118654755
class Animal {
speak() {
return this;
}
static eat() {
return this;
}
}
let obj = new Animal();
obj.speak(); // the Animal object
let speak = obj.speak;
speak(); // undefined
Animal.eat() // class Animal
let eat = Animal.eat;
eat(); // undefined
Math.pow() 대체
console.log(3 ** 4) // 81
배열내의 해당 값 여부 반환
const a = [1, 2, 3]
console.log(a.includes(2)) // true
문자열 앞뒤로 지정한 길이가 될때까지 문자 추가
console.log('5'.padStart(3, '0')) // 005
console.log('test'.padEnd(7, '.')) // test...
비동기 처리인 Promise 를 좀 더 동기적인 절차적 프로그래밍으로 처리되도록 구성
function resolveAfter2Seconds() {
return new Promise(resolve => {
setTimeout(() => {
resolve('resolved');
}, 2000);
});
}
async function asyncCall() {
console.log('calling');
const result = await resolveAfter2Seconds();
console.log(result);
// expected output: "resolved"
}
asyncCall();
객체를 enumerable 배열 형태로 반환, 각각의 항목은 [키, 값]
형태
const object1 = {
a: 'somestring',
b: 42
};
for (const [key, value] of Object.entries(object1)) {
console.log(`${key}: ${value}`);
// "a: somestring"
// "b: 42"
}
객체를 enumerable 배열 형태로 반환
const object1 = {
a: 'somestring',
b: 42
};
console.log(Object.values(object1));
// expected output: Array ["somestring", 42]
,
다음 값이 없어도 처리 가능
var arr = [1, 2, 3,,,];
arr.length; // 5
var object = {
foo: "bar",
baz: "qwerty",
age: 42,
};
const object1 = {
property1: 42
};
const descriptors1 = Object.getOwnPropertyDescriptors(object1);
console.log(descriptors1.property1.writable); // true
console.log(descriptors1.property1.value); // 42
비동기 처리의 동기 처리를 반복문 내에서 처리 가능하도록 지원
async function* asyncGenerator() {
let i = 0;
while (i < 3) {
yield i++;
}
}
(async function() {
for await (let num of asyncGenerator()) {
console.log(num);
}
})(); // 0 / 1 / 2
(기존 방식) 그룹 인덱스로 처리
const regex = /(\d{4})-(\d{2})-(\d{2})/;
const matchers = regex.exec('2020-12-02');
console.table(matchers)
그룹명을 통한 접근
let regx = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
let result = regx.exec('2020-12-02');
result[0] === '2020-12-02';
result.groups.year === '2020' === result[1];
result.groups.month === '12' === result[2];
result.groups.day === '02' === result[3];
그룹값 중복 확인
정의된 명칭으로 잡힌 그룹을 뒤에서도 동일하게 적용
let duplicate = /^(?<half>.*).\k<half>$/;
duplicate.test('a*b'); // false
duplicate.test('a*a'); // true
매칭 그룹 재조합
replace()를 정규식을 통해 바로 재조합 가능
let regx = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
let result = "2020-12-02".replace(regx, '$<day>/$<month>/$<year>');
console.log(result === '02/12/2020');
그룹 일치 없을때 undefined
로 초기화
let regx = /^(?<optional>\d+)?$/;
let matchers = regx.exec('');
matcher[0] === '';
matchers.groups.optional === undefined;