// 배열 리터럴
let matrix = [[1, 2], [3, 4]];
// 콤마 사이의 값을 생략하면 정의되지 않은 요소가 들어간다
let sparseArray = [1, , , , 5];
console.log(sparseArray); // [ 1, <3 empty items>, 5 ]
// 마지막 표현식 다음에 콤마가 단 하나 있으면 정의되지 않은 요소가 만들어지지는 않는다.
let lastSparse = [0, ];
console.log(lastSparse); // [0]
//하지만 인덱스로 배열에 접근하면 undefined 로 평가된다
console.log(lastSparse[1]); // undefined
//객체 리터럴
let p = { x: 2.3, y: -1.2 };
function 함수명 (0개 이상의 매개변수){ 동작 내용 }
함수 정의 표현식은 함수를 정의하며, 그 값은 함수이다.
함수 리터럴이라고 부를 수도 있다.
let square = function (x) {
return x * x;
};
함수 표현식(Function Expresion)
이란 함수 선언
을 값
처럼 활용하는 것을 말한다.
//다른 함수의 파라미터로 함수를 선언해서 전달하는 것도 함수 표현식이다.
myFunction (num1, function(){
console.log('function')
});
💡 함수 선언문과 함수 표현식의 차이
함수 선언문은 함수 호출 전에도 작동하지만(호이스팅 발생), 함수 표현식으로 작성한 함수는 변수의 특성상 선언 이전에 접근할 수 없다.
print(); //hi
function printHi(){
console.log('hi');
}
printBye(); // ReferenceError: Cannot access 'printBye' before initialization
let printBye = function(){
console.log('Bye');
}
함수 선언문은 함수 스코프를 가지고, 함수 표현식은 할당 연산자(var, let, const)에 따라 스코프가 달라진다.
if(true){
function printHi(){
console.log('Hi');
}}
printHi(); //Hi
dot notation(점 표기법) 객체.key
공백
이나 .
이 없는 문자열일 때 사용 가능숫자형 문자열
일 때도 사용 불가.
점을 나열해서 접근bracket notation(대괄호 표기법) 객체['key']
문자열
을 입력해야 한다.계산 결과
일 때도 사용 가능+
로 문자열을 결합해서도 사용 가능[]
를 나열해서 값에 접근(read).
이나 [
앞의 표현식이 null
이나 undefined
인 경우 TypeError 발생한다.
옵션 체인
은 ?.
또는 ?[]
를 사용하여 에러 발생을 막고 undefined로 평가되도록 하는 접근 표현식이다.
let a = { b: null };
console.log(a.b.c); // TypeError
console.log(a.b?.c.d); // undefined
//그러나 a.b는 객체인데, 그 안에 c 프로퍼티가 없으면 TypeError 발생
a = { b: { x: 1 } };
console.log(a.b?.c.d); // TypeError
함수나 매서드를 호출(실행)하는 문법
let square = function(x) { return x*x; }; //함수 정의 표현식
function(3); // 호출 표현식
호출 표현식 맨 앞에 있는 표현식이 프로퍼티 접근 표현식이라면 이 호출은 매서드 호출이라고도 한다.
매서드 호출에서 프로퍼티 접근 대상인 객체 또는 배열은 함수 바디가 실행되는 동안 this
키워드의 값이 된다.
?.()
를 사용하면 괄호 왼쪽 표현식이 null
, undefined
으로 평가 될 때 TypeError가 발생하지 않고, undefined
로 평가된다.
let noFunction = null;
console.log(noFunction(3)); // TypeError: noFunction is not a function
console.log(noFunction?.(3)); // undefined
[+ 스터디 후 내용 추가] 스터디원들 진짜 다 천재 만재인듯....
하지만 ?.()
는 null
이나 undefined
인지만 체크하며, 값이 실제로 함수
인지 체크하지 않는다.
let noFunction = ‘str’;
console.log(noFunction?.(3)); // SyntaxError: Invalid or unexpected token
?.()
왼쪽의 값이 null 이나 undefined 라면 괄호 안에 있는 함수 인자 표현식은 더 이상 평가하지 않고 바로 전체를 undefined
로만 평가한다.
function calculator(a, b, func) {
return func?.(a, b);
}
console.log(calculator(6, 7, (a, b) => a*b)); //42
console.log(calculator(6, 7)); //undefined
정리
myObject.keyFunction()
myObject가 객체이고,
그 안에 keyFunction 프로퍼티가 있고,
그 프로퍼티 값이 함수여야 TypeError 발생하지 않음
myObject?.keyFunction()
myObject가 null이나 undefined가 아니라면,
그 안에 keyFunction 프로퍼티가 있고,
그 프로퍼티값이 함수여야 TypeError 발생하지 않음
myObject.keyFunction?.()
myObject는 null이나 undefined가 아니어야 하고,
그 안에 keyFunction 프로퍼티가 없거나, 프로퍼티 값이 null이라면 undefined로 평가됨
새로운 객체를 생성하고, 함수(생성자)를 호출해 프로퍼티를 초기화(생성)한다.
생성자 함수를 만들고 호출할 때 전달 인자(매개변수)가 없다면 괄호는 생략할 수 있다.
// 생성자 함수 이름의 첫 글자는 대문자로 시작
function User(name) {
this.userName = name;
this.level = 1;
}
// 생성자 함수는 반드시 'new'를 붙여서 실행한다
let newUser = new User("김자바");
console.log(newUser);
// User { userName: '김자바', level: 1 }
let secretUser = new User;
console.log(secretUser);
//User { userName: undefined, level: 1 }