[개발자되기: javascript koans] Day-16

Kyoorim LEE·2022년 5월 18일
0

Introduction.

테스트코드

TDD (Test-Driven Development, TDD)

 - expect(테스트하는값).기대하는 조건
 
expect(isEven(3)).to.be.true => 'isEven(3)'의 결과값은 (true)이어야 한다'
expect(1 + 2).to.equal(3) => 'sum(1, 2)의 결과값은 3과 같아야(equal) 한다'
	- '기대하는조건'에 해당하는 함수 matcher
'참인 것이어야 한다' => to.be.true
'3과 같아야 한다' => to.equal(3)

Types-part1

느슨한 동치연산(==, loose equality), 엄격한 비교(===, strict equality)

expect(123 - '1').to.equal(122) // '숫자 - 문자열'인 경우 숫자처럼 계산
expect(1 + true).to.equal(2) // 숫자 + boolean의 경우 숫자처럼 계산
expect('1' + true).to.equal('1true)

LetConst

var vs let vs const

- `let` 변수는 초기화하기 전에는 읽거나 쓸 수 없는 반면 `var` 변수는 선언하기 전이라도 호이스팅으로 인해 `undefined` 값 리턴

호이스팅

- var는 호이스팅 발생

TDZ (Temporal Dead Zone, 시간상 사각지대) :

사각지대가 코드의 실행순서(시간)에 의해 형성됨

function do_something() {
  console.log(bar); // undefined
  console.log(foo); // ReferenceError
  var bar = 1;
  let foo = 2;
}
{
    // TDZ가 스코프 맨 위에서부터 시작
    const func = () => console.log(letVar); // OK
    // TDZ 안에서 letVar에 접근하면 ReferenceError
    let letVar = 3; // letVar의 TDZ 종료
    func(); // TDZ 밖에서 호출함
}

Scope

함수표현식

- 함수를 변수에 할당한 형태
- 호이스팅이 일어난다

```jsx
function add (x, y) {
	return x + y;
}
```

함수선언식

- function키워드를 사용하여 함수를 선언
- 호이스팅이 일어나지 않는다 

```jsx
const add = function (x, y) {
	return x + y;
}
```

스코프

클로저

ArrowFunction

  • 화살표 함수
    const adder = function (x, y) {
    	return x - y;
    }
    
    const adder (x, y) => x - y 

Types-part2

원시 자료형

- immutable
- 원시자료형을 변수에 할당할 경우 값 자체의 복사가 일어남

참조 자료형

- heap: 저장 공간
- 주소를 할당함 - immutable하지 않음
- 언제나 데이터가 늘어나고 줄어들 수 있음 (동적으로 변함)
  • .deep.equal
deepEquals({a:1, b: {c:3}},{a:1, b: {c:3}}); // true
deepEquals({a:1, b: {c:5}},{a:1, b: {c:6}}); // false

=> 객체의 키 & 값 모두 똑같은지를 확인할 수 있음
출처: https://im-developer.tistory.com/153 [Code Playground]

ex) 연습문제

const person = {
      son: {
        age: 9,
      },
    };
    const boy = person.son;
    boy.age = 20;
    expect(person.son.age).to.equal(20);
    expect(person.son === boy).to.equal(true);
    expect(person.son === { age: 9 }).to.equal(false);//  주소가 다른 객체일 수 있으므로
    expect(person.son === { age: 20 }).to.equal(false); // 주소가 다른 객체일 수 있으므로 
    //person.age 의 값음 { age: 20 }임

Array

pop, push, shift, unshift vs slice

slice

- `arr.slice`는 arr의 값을 복사하여 새로운 배열을 리턴
- arr 전체복사 방법 => `arr.slice(0);`
- 연습문제
it('Array 메소드 slice를 확인합니다.', function () {
    const arr = ['peanut', 'butter', 'and', 'jelly'];
 expect(arr.slice(1)).to.deep.equal(['butter', 'and', 'jelly]); // 매개변수가 1개일 경우 앞에서부터 자른 후 남은 값을 리턴한다
    expect(arr.slice(0, 1)).to.deep.equal( ['peanut']);//
    expect(arr.slice(0, 2)).to.deep.equal(['peanut', 'butter]);// 
    expect(arr.slice(2, 2)).to.deep.equal([]); // 첫번째 매개변수가 두번째 매개변수보다 크므로 이 경우는 slice 가 불가함 <-> substring
    expect(arr.slice(2, 20)).to.deep.equal(['and', 'jelly']); // 
    expect(arr.slice(3, 0)).to.deep.equal([]);// 첫번째 매개변수가 두번째 매개변수보다 크므로 이 경우는 slice 가 불가함 <-> substring 
    expect(arr.slice(3, 100)).to.deep.equal(['jelly']); //
    expect(arr.slice(5, 1)).to.deep.equal([]); // 첫번째 매개변수가 두번째 매개변수보다 크므로 이 경우는 slice 가 불가함 <-> substring 
function () {
    const arr = ['zero', 'one', 'two', 'three', 'four', 'five'];
    function passedByReference(refArr) {
      refArr[1] = 'changed in function';
    } 
    passedByReference(arr);
    expect(arr[1]).to.equal('changed in function'); 
    const assignedArr = arr;
    assignedArr[5] = 'changed in assignedArr';
    expect(arr[5]).to.equal('changed in assignedArr');// assignedArr에 arr를 할당해주었으니 	arr의 값이 변경됨 
    const copiedArr = arr.slice();
    copiedArr[3] = 'changed in copiedArr';
    expect(arr[3]).to.equal('three'); //arr.slice()는 arr전체를 복사하는 메소드로, 복사된 arr의 값이 바뀐 것이기 때문에 원래 arr의 값은 바뀌지 않음
  });

Object

  • 객체에는 길이가 없음
const emptyObject = {};
emptyObject.length = undefined; 
  • Object.keys(obj).length를 통해서 키의 개수 구할 수 있음

얕은 복사 (shallow copy)

- 데이터는 같은데 주소가 같음

깊은 복사 (deep copy)

- 주소가 다름, 데이터도 다름

https://scotch.io/bar-talk/copying-objects-in-javascript
https://medium.com/watcha/깊은-복사와-얕은-복사에-대한-심도있는-이야기-2f7d797e008a

this

// 웹 브라우저에서는 window 객체가 전역 객체
console.log(this === window); // true
a = 37;
console.log(window.a); // 37
this.b = "MDN";
console.log(window.b)  // "MDN"
console.log(b)         // "MDN"

전역 실행 맥락에서 this는 엄격 모드 여부에 관계 없이 전역 객체를 참조합니다.

참조 => https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this

Object.assign()

Object.assign() 메서드는 출처 객체의 '열거 가능한 자체 속성'만 목표 객체로 복사합니다. (...) 목표 객체의 속성 중 출처 객체와 동일한 키를 갖는 속성의 경우, 그 속성 값은 출처 객체의 속성 값으로 덮어씁니다.

Object.assign(target, ...sources)
target: 목표 객체. 출처 객체의 속성을 복사해 반영한 후 반환할 객체입니다.
...sources: 출처 객체. 목표 객체에 반영하고자 하는 속성들을 갖고 있는 객체들입니다.

const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target);
// expected output: Object { a: 1, b: 4, c: 5 }
console.log(returnedTarget);
// expected output: Object { a: 1, b: 4, c: 5 }

출처: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

SpreadSyntax

Rest Parameter

함수의 전달인자를 배열로 다룰 수 있게 함 → 항상 배열
ex) 연습문제

function getAllParamsByArgumentsObj() {
      return arguments;
    }
    const restParams = getAllParamsByRestParameter('first', 'second', 'third');
    const argumentsObj = getAllParamsByArgumentsObj('first', 'second', 'third');
//
    expect(restParams).to.deep.equal( ['first', 'second', 'third']); //
    expect(Object.keys(argumentsObj)).to.deep.equal(['0', '1', '2']); // 객체의 인덱스 값이 자동적으로 '키'가 됨
    expect(Object.values(argumentsObj)).to.deep.equal(['first', 'second', 'third']); //

ex) 연습문제

it('Rest Parameter는 전달인자의 일부에만 적용할 수도 있습니다.', 
	function () {
    // rest parameter는 항상 배열입니다.
    	function getAllParams(required1, required2, ...args) {
      		return [required1, required2, args];
    }
    expect(getAllParams(123)).to.deep.equal([123, undefined, []]);// 

배열에서의 SpreadSyntax

var parts = ['shoulders', 'knees'];
var lyrics = ['head', ...parts, 'and', 'toes'];
// ["head", "shoulders", "knees", "and", "toes"]

객체에서의 SpreadSyntax

var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };
var clonedObj = { ...obj1 };
// Object { foo: "bar", x: 42 }
var mergedObj = { ...obj1, ...obj2 };
// Object { foo: "baz", x: 42, y: 13 }

Destructuring Assignment (구조분해할당)

rest & spread 문법

ex) 연습문제

 it('rest/spread 문법을 배열 분해에 적용할 수 있습니다', () => {
    const array = ['code', 'states', 'im', 'course']
    const [start, ...rest] = array
    expect(start).to.eql('code')// 
    expect(rest).to.eql(['states', 'im', 'course']) // rest는 항상 배열

Object destructuring (객체 구조분해)

let {var1, var2} = {var1:, var2:}
//
let options = {
  title: "Menu",
  width: 100,
  height: 200
};
let {title, width, height} = options;
alert(title);  // Menu
alert(width);  // 100
alert(height); // 200
profile
oneThing

0개의 댓글