strict mode

각 스크립트의 초반에 'use strict'라고 적어두면 엄격한 모드의 자바스크립트를 작성할 수 있다.

스티릭트 모드는 두가지 역할을 한다.

  1. 특정 작업을 금지한다.
  2. 실제로 눈에 보이는 오류를 생성한다.
    실제 작동하는 것 예시들을 보자면
//'use strict';

let hasDriversLicense = false;
const passTest = true;

if (passTest) hasDriverLicense = true;// hasDrivers에 s를 뻈다. 
if (hasDriversLicense) console.log("you are driver!");

아무것도 기능하지 않는다. 하지만 초기에 'use strict'를 넣는다면 스트릭트 모드가 설정되어 다음과 같은 오류메시지가 나타난다.

따라서 에러를 고칠수 있다.


  1. 또한 예약된 키워드를 변수나 다른 이름으로 사용하지 못하게 함으로서 개발자의 인터페이스를 지켜준다.

이러한 이유들로 모든 자바스크립트 파일작성시 기본적으로 'use strict'를 항상 적고 시작한다.

함수

함수는 함수 표현식과 함수 선언식이있다. 두 형태의 차이는 호이스팅의 차이에서 발생하는데 함수 선언식은 호이스팅시 가장 위로 올라가서 가장위에 함수를 호출해도 호출이 되는 반면 함수표현식은 해당변수에 무기명함수가 정의된 그 코드에서 해당 함수가 선언이 되기 때문에 표현식 이전에 함수를 표현 한 코드에서는 정의되지 않는 함수라고 나온다.

function howOld (birth, current) {
  return current - birth;
}

const howOld2 = function (birth, current) { // 함수 표현식
  return current - birth;

함수는 데이터 타입이 아니다. 그냥 값일 뿐이다. 따라서 값이라면 그것을 변수에 저장할수 있다.

console.log(Boolean(howOld)) // true;
console.log(typeof(howOld)) // function ...? 버그라고 생각한다. 뭐지?? 

두개의 표현식중 어떤 표현식으로 함수를 사용해야 하느냐? 이런 문제는 개발자 개인의 취향이다. 함수표현식은 해당 함수를 맨위에 정의하게 만든다. 그래야 해당 함수가 아래 코드에서 호출시 어디서나 동작할수 있기 때문이다. 즉, 코드가 더 구조화 된다.

함수표현식의 다른표현으로 arrow function이 있다.

const howOld = (year, ...) => {
  ...
  return ...
}

❓ 간단한 과정조차도 함수를 만드는 이유가 있다면?
코드를 반복하지 않는 것이다. 중복코드를 만들지 않는 DRY 원리를 따르는 것

  • 코드를 고칠때에 여러곳에서 코드를 고쳐야 하기 때문이다. 이는 코드실수로 이어질수 있으며 버그를 유발시킬수 있다.

💡 vscode에서 option + up || down 키를 누르면 해당 코드줄을 위 아래로 간단히 옮길수 있다.

함수를 만들때에는 하나의 기능에 충실하게 작동하도록 만들어야 한다. 그래야 다른 용도로 썻을때 해당 코드가 작동하며 여러곳에서쓰이는 코드일수록 매우 강력한 힘을 낼수 있다.

Array

배열은 두가지 방법으로 생성할수 있다.

  • 리터럴
const arr = [1, 2, 3];
  • 생성자
const arr = new Array(1, 2, 3);

두개의 배열생성은 동일한 효과를 지닌다. 생성자의 경우 new 키워드로 생성자를 호출하여 Array객체를 생성한다. 결국 두방법다 Array객체를 생성하는 방식이다.

const arr = [1, 2, 3];
const arr2 = new Array(1, 2, 3);
console.log(typeof arr); //object
console.log(typeof arr2); //object
arr[2] = 6;
console.log(arr) // [1 ,2 ,6]
arr = ['a', 'b']; // error! Assignment constant variable

여기서 착각했던 점을 조심하자면 배열이 const로 정의되어 있는데 배열이 바뀔수가 있나? 라는 점인데,

const 변수는 immutable 한 변수만 바꿀수 없다. 객체는 mutable한 변수이기 때문에 해당요소 값을 바꿀 수 있다.

추후에 immutable한 변수 값과 mutable변수에 대한 자바스크립트의 값 저장방식에 대해서 설명하면서 풀이하자.

안되는 것은 배열의 요소 변경이 아니라 해당 배열의 전체값을 변경하는 부분들을 허용하지 않는다.

배열에서만 동작하는 메서드들이 있다.

  • push(), pop() : 배열의 끝에 원소를 추가하고 길이를 반환한다. 배열의 끝에 원소를 삭제하고 삭제한 원소를 반환한다.
  • unshift(), shift() : 배열의 처음에 원소를 추가하고 길이를 반환한다. 배열의 끝에 원소를 삭제하고 삭제한 원소를 반환한다.

객체

점 표기법과 대괄호 표기법이 있는데 두개의 차이점은 대괄호 표기법은 조회활 객체의 프로퍼티의 키값을 의미하는 다른 변수로 수정하거나 변경해서 변수로 전달할수 있는 것,

점 표기법은 프로퍼티의 키값을 받으므로 그렇지 않은 것의 차이가 있다.

// Dot vs. Bracket Notation
const jonas = {
  firstName: 'Jonas',
  lastName: 'Schmedtmann',
  age: 2037 - 1991,
  job: 'teacher',
  friends: ['Michael', 'Peter', 'Steven']
};
console.log(jonas);

console.log(jonas.lastName);
console.log(jonas['lastName']);

const nameKey = 'Name';
console.log(jonas['first' + nameKey]); // 출력성공
console.log(jonas['last' + nameKey]); // 출력성공

// console.log(jonas.'last' + nameKey) // 에러

const interestedIn = prompt('What do you want to know about Jonas? Choose between firstName, lastName, age, job, and friends'); // job 입력

console.log(jonas[interestedIn]) // 'teacher';
console.log(jonas.interested) // undefined 

💡 이러한 .점과 [] 대괄호 표기법은 일종의 연산자로서 연산자 우선순위의 최상위 권에 위치한다. 점 표기법은 member Access 연산자이고 대괄호 표기법은 member compute 연산자이다.
둘다 left to right 순서로 연산이 된다.

객체 메서드

const jonas = {
  firstName: 'Jonas',
  lastName: 'Schmedtmann',
  age: 2037 - 1991,
  job: 'teacher',
  friends: ['Michael', 'Peter', 'Steven']
  calcAge: function (age){
    return 2021-age;
  }
};

console.log(jonas.calcAge(1994)) // 27
console.log(jonas[`calcAge`](1994)) // 27

이렇게 함수의 키값과 대칭되는 value 값으로 함수표현식을 준다면 함수표현식을 어떠한 값을 주므로 프로퍼티의 value가 될수 있다. arrow function으로도 가능하다. ( 다만, arrow function안에서의 this의 사용은 제한된다. this 바인딩을 하지 않는다. this에 대해서는 다음에 설명하자)

이후에 값을 호출할때도 멤버에 접근해서 함수처럼 사용한다.

this 바인딩에 관해서 말해보자면 객체에서 this는 해당하는 함수를 호출하는 대상에 대해서 적용되는데 이대상은 . 연산자에 대해서 적용된다. 즉, 위의 코드에서 jonas.calcAge()에서 calcAge() 안에 this. 연산자로 호출하는 jonas를 지칭한다. thisjonas객체를 지정한다.
💡그렇다면 this 키워드 대신 해당하는 객체의 이름을 적어도 되지않나?
맞다. 작동한다. 하지만 만약 객체의 이름을 바꾼다면 this대신 객체 이름을 적은 코드도 바꿔야 한다. DRY 원칙에 위배 된다!

calcAge: function (){
    return 2021-this.age; 

이렇게 객체 메소드를 변경한다면 해당 함수안에 매개변수 값을 넣지 않고도 같은 값이 출력될 것이다.

console.log(jonas.calcAge()) 
console.log(jonas.calcAge()) 

그리고 해당 함수를 여러번 출력할 경우이다. 위코드는 굳이 두번의 같은 결과를 내놓는 연산을 수행한다. 그럴필요없이 같은 값을 출력하는 것이면 해당 결과를 저장해 두면된다.

calcAge: function (){
  	this.currentAge = 2021-this.age;
    return this.currentAge

이렇게 되면 this는 jonas라는 객체를 가르키고 jonas라는 객체에 currentAge라는 속성을 추가 시킨다면 해당 프로퍼티에 값을 저장시킨다.

이후 출력시

console.log(jonas.currentAge) // undefined
console.log(jonas.calcAge()); // 값 계산후 currentAge 속성 새성넣기
console.log(jonas.currentAge) // 정상 출력
console.log(jonas.currentAge) // 정상 출력

를 수행한다면 문제없이 출력이된다.

profile
일상을 기록하는 삶을 사는 개발자 ✒️ #front_end 💻

0개의 댓글