JavaScript

개발자 우니·2020년 9월 24일
0

프로토타입, 객체지향의 언어 Constructor & Instance

어떤 객체가 만들어지기위해 그 객체의 모태가 되는 원형이 프로토타입.
inheritance를 가능하게 해주는 것이 js의 prototype의 property이다.
JS는 객체지향의 언어 , 프로토타입 기반 언어 원래는 클래스라는 개념이 없어서 기본적으로 상속기능이 없다. 그래서 프로토타입에서 상속기능을 흉내. ECMA6에서 class 문법이 추가됨.

JavaScript에서 거의 모든 객체는 Object의 인스턴스입니다. 일반적인 객체는 Object.prototype 에서 속성과 메서드를 상속받으며,

function Person() {
	this.eyeColor = "blue";
    this.age = 20;
}

let James = new Person();
let Jerry = new Person();

==> 함수와 new 를 통해서 class를 흉내냄 (상속가능)


function Person() {}

Person.prototype.eyeColor = "blue";
Person.prototype.age = 20;

let James = new Person();
let Jerry = new Person();

==> Person.prototype이라는 빈 객체가 어딘가에 존재하고 생성된 James,Jerry는 prototype을 통해서
빈 객체에 담긴 property들을 가져다 쓴다.

객체는 언제나 함수로 생성된다.
Object 자체가 JS에서 기본적으로 제공하는 함수

let obj = {};
let obj = new Object(); 와 동일한 의미

함수가 정의되면
1. constructor (생성자) 자격이 부여된다 -> new 를 통해서 객체를 만들 수 있게 됨
2. 해당 함수의 prototype object 생성 및 연결 ( _proto_)

함수를 콘솔창에 찍어보면 constructor 와 _proto_ 가 뜬다.
constructor 는 객체를 생성하는 함수를 보여주고,
_proto_ 가 객체 원형을 연결해준다. (prototype link)

참고 링크 : http://insanehong.kr/post/javascript-prototype/

closure

여러 함수형 프로그래밍 언어에서 등장하는 보편적인 특성.
함수를 선언할 때 만들어지는 유효 범위가 사라진 후에도 호출할 수 있는 함수
outer function이 리턴된 후에도 inner function이 outer 범위의 변수에 접근할 수 있는 함수.
자신이 생성될 때의 scope에서 알 수 있던 변수들 중에 언젠가 자신이 실행될 때 사용할 변수들만을 기억해서 유지시키는 함수.
outer function에서 선언한 변수를 참조하는 inner function에서 발생하는 현상.

inner함수의 실행 시점에는 outer 함수는 이미 실행이 종료이 상태인데 outer 함수의 Lexical Environment에 접근할 수 있는 이유는?
-> 가비지 컬렉터의 동작방식 때문 (가비지 컬렉터는 어떤 값을 참조하는 변수가 하나라도 있다면 그 값은 수집대상에 포함시키지 않는다)

function retirement(retirementAge) {
	return function(yearOfBirth) {
    		let age = 2020 - yearOfBirth;
        	console.log(`you have ${retirementAge - age} years left until retirement.`);
    }
}

let countryA = retirement(65);
let countryB = retirement(70);

countryA(1980);
countryB(1980);

retirement(65)(1980);     ===> countryA(1980)과 동일
retirement(70)(1980);     ===> countryB(1980)과 동일

inner function에서 outer function의 변수인 retirementAge가 outer function이 리턴됐음에도 호출가능하다.

Shallow Merge, Deep Merge (얕은 복사, 깊은 복사)

어떤 객체를 복사할때 객체 내부의 모든 값을 복사해서 완전히 새로운 데이터를 만들고자할때, 프로퍼티 값이 기본형 데이터일 경우에는 그대로 복사하면 되지만, 참조형 데이터는 그 내부의 프로퍼티들을 모두 복사해줘야한다.

Shallow Merge

동일한 key가 존재할 경우 대체한다.

1. Object.assign 
2. Spread Operator

------------------------------------

const A1 = {
    B: 2,
    C: 1   
}

const A2 = {
    B: 3,
    D: 2  
}

Object.assign(A1, A2);   ===> { B: 3, C: 1, D: 2 }
B의 value가 다른데 A2의 B로 대체되었다.

console.log({...A1,...A2}); 동일 결과 출력

----------------------------------------
const A3 = {
    B: {
        C: 1
    }
}

const A4 = {
    B: {
        D: 2
    }
}


Object.assign({}, A3, A4); ===>  {B: { D: 2 }}
B라는 동일 key를 대체해서 {D:2}가 들어간다.
console.log({...A3,...A4}); 동일 결과 출력

Object.assign 과 spread operator의 차이는?
-> Object.assign은 첫번째 인자를 기준으로 병합되는데 병합된 후에 첫번째 인자의 값 자체가 변한다. 반면에, spread operator는 그대로 기존값을 유지

const A1 = {
    B: 2,
    C: 1   
}

const A2 = {
    B: 3,
    D: 2  
}


Object.assign(A1,A2);   ===> { B: 3, C: 1, D: 2 }
console.log(A1);        ===> { B: 3, C: 1, D: 2 }
console.log(A2);        ===> { B: 3, D: 2 }
A1이 기존과 다르게 변한것을 확인할 수 있다.


const A1 = {
    B: {
        C: 'C1',
      	E: 'E'
    }
}

const A3 ={...A1};
A3===A1     ===> false (같아보이지만 같지 않다! 각자 다른 메모리에 저장된 값)

Deep Merge

한 객체의 데이터 공유가 아닌 똑같은 구조의 객체를 만들어서 따로 사용하고자 할 때는 deep merge가 필요하다.
js의 유틸리티 라이브러리 lodash 사용하는 방법

import merge from 'lodash/merge'

const A1 = {
    B: {
        C: 'C1',
      	E: 'E'
    }
}

const A2 = {
    B: {
      	C: 'C2',
        D: 'D',
    }
}

console.log(merge(A1, A2));
===>
{
  B: 
    {
      C: 'C2',
      D: 'D',
      E: 'E'
    }
}
두 개가 병합되었지만 두번째인자인 A2의 C 값이 들어왔다.

JSON.parse & JSON.stringfy
JSON.stringfy로 객체의 데이터를 json 타입으로 변환한 후에, JSON.parse나 eval() 사용해서 다시 객체로 만드는 방법

Set

set은 데이터타입 중 하나
중복되지 않은 값들을 가진 배열

const a = new Set();
console.log(a);      ===> Set{}

const foo = new Set([ 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5 ]);
console.log(foo);     ===> Set { 1, 2, 3, 4, 5 }

set의 메서드 : add (이미 있는 요소를 추가한다면 무시된다) / size(전체 길이) / clear (전부 삭제) / delete(특정 요소 삭제) / has (있는지 없는지 boolean으로)

const b = new Set(['a','b']);
console.log(b);       ===> Set {'a', 'b' }
b.add('c');            ===> Set { 'a', 'b', 'c' }
console.log(b.size);    ===> 3 

Event Bubbling / Event Capture

Event Bubbling : 하위 요소의 이벤트가 상위 요소들로 전달되는 특성

브라우저는 특정 화면 요소에서 이벤트가 발생했을 때 그 이벤트를 최상위에 있는 화면 요소까지 이벤트를 전파시킵니다.
“Trigger clicks all the way up”

console 결과는 three > two > one 으로 나타난다. two를 클릭했다면 two > one 으로 나타난다.

Event Capture : 반대로 상위에서 하위로 이벤트가 전달되는 특성

addEventListener에 3번째 인자로 {capture: true;}를 설정해준다. 상위->하위 로 간다는 걸 알려준다.

결과는 'three' div 클릭시 one > two > three 로 출력된다.

이런 전달되는 특성을 이용하고 싶지 않다면 function에

event.stopPropagation() ; 

을 넣어주면 된다. 그러면 이벤트가 클릭한 요소에서만 나타난다.

Array 원본 배열유지, 신규 배열 생성

-> concat, slice, filter

concat의 경우는 배열안의 요소만 합쳐준다.

let arr = [1,2,3];

let newArr = arr.concat(4,5,[6,7]);
console.log(newArr);        ===> [ 1, 2, 3, 4, 5, 6, 7 ]

slice(number, -1) 처럼 -1같은 음수를 인덱스로 사용하면 마지막부터 시작이 되므로 -1은 마지막 요소의 전에서 잘린다. -2라면 마지막 요소의 전전에서 잘린다.
negative index indicating an offset from the end of the sequence.

profile
It’s now or never

0개의 댓글