TIL021_210413

keepcalm·2021년 4월 13일
0

TIL

목록 보기
21/33
post-thumbnail

🍊 감상

아직까진 재밌게 하고 있다.
복습하고 나니 모호하게 있던 개념들이 어느 정도 보이고 무엇보다 당시에는 어렵다고 느꼈던 부분들이 이해될 때 즐거웠다.
다른 사람들 코드를 막연하게 따라 하며 '이게 뭐지?'하고 생각했던 것들을 하나 둘 깨닫게 될 때 쾌감이 장난 아님.

📙 열품타 코딩 시간 10hour
👍🏼 -
👎🏼 -

🚀 목표

  • Udemy에서 Javascript 강좌 수강하기 (332/682)
  • 커밋 연속 30일 달성하기 (7/30, 4.13 완료)
  • 드림코딩 자바스크립트 기초 강의 완강 (8/23)
  • ~~복습: TIL014-TIL019 (완료)~~

📣 복습: The Web Developer Bootcamp

javascript

⭐️⭐️⭐️ arrow function과 this

눈물의 arrow function과 this...삽질 많이 함...

traditional function은 함수가 실행되는 곳의 영향을 받는다
하지만 arrow functiondms 함수가 만들어진 곳에 scope된다

참고링크: WDS
참고링크: 모던 자바스크립트 튜토리얼
참고링크: 코드깎는노인
참고링크: Hitesh
참고링크: poiemaweb
참고링크: poiemaweb

normal function already create the variable with the function keword
function sum(a,b){ return a+b; }
but arrow function, we have to create own variable to store the function
let sum2 = (a,b) => a+b;

arrow function은 익명 함수에서 빛을 발한다 -> 화살표 함수는 현재의 컨텍스트를 잃지 않을 수 있다
화살표 함수는 this가 없다!

scope: 변수가 유효한 영역

let oo = {
	name: "asdf",
    kk: {
    	cc: function testFunction() {
    		console.log(this)
        	return null
    },
};

oo.kk(); // oo가 this가 됨
oo.kk.cc(); //oo.kk가 this가 됨 블록 안을 출력해줌
let ff = oo.kk.cc.bind(45); // 함수에서의 this가 무조건 45가 된다
//this =>  bind(this)
ff(); //45

bind는 함수에만 붙어있다 - 바인드는 함수를 리턴해준다

lexical this 설명

const cameras = {
	price: 600,
    weight: 2000,
    myDes: function() {
    	return `This canon camera is of ${price}$`
	}
}
console.log(cameras.myDes());
//error: price is not defined

const cameras = {
	price: 600,
    weight: 2000,
    myDes: function() {
    	return `This canon camera is of ${this.price}$`
	}
}
console.log(cameras.myDes()); 
//This canon camera is of 600$
//Nightmare of this keyword: automatically bind, no way to controll it

const cameras = {
	price: 600,
    weight: 2000,
    myDes: () => {
    	return `This canon camera is of ${this.price}$`
	}
}
console.log(cameras.myDes()); 
//This canon camera is of undefined$
//arrow function: nothing is binded 

화살표 함수의 this는 언제나 상위 스코프의 this -> lexical this

default parameters

function rollDie(numSides = 6) {
    return Math.floor(Math.random() * numSides) +1
}

spread

새로운 array 만듦

Math.max(1,2,3,4) //4
const nums = [1,2,3,4]
Math.max(nums) //NaN
Math.max(...nums) //4

const allPets = [...cats, ...dogs] //더해짐

{...[2,4,6,8]} //indices are used as the key
// {0:2, 1:4, 2:6, 3:8}

rest parameter

function raceResults(gold, silver, ...everyoneElse) {
	console.log(`gold medal goes to ${gold}`)
    console.log(`silver medal goes to ${silver}`)
	console.log(`thanks to ${everyoneElse}`)
}

destructing

const scores = [1,2,3,4];
// 이런 식으로 분리할 수 있음
const highScore = scores[0];
// 하지만 더 쉬운 방법, 
const [gold,silver,...everyoneElse] = scores;
gold; //1
// score은 변하지 않은 상태에서 extract하는 것, position에 따라서
const user = {
	name: 'nyangnyang',
    born: 1930
    died: 1980
}
// 이것도 가능하긴 함
const userName = user.name;

// 더 효율적인 코드는?
const {name} = user;

// 다른 이름을 붙여주고 싶다면
const {born: birthYear} = user;

// 아직 살아있는 다른 유저가 있다면?
const user2 = {
	name: 'monkmonk',
    born: 1970
}

const {died} = user2; // undefined

// defalt value 주기
const {died = 'N/A'} = user2;
// 방법1
function userBio(user) {
	return `${user.born} ${user.died}`
}    

// 방법2
funcion userBio(user) {
	const {born, died} = user;
    return `${born}, ${died}`
}    

// 방법3
function userBio({born, died = 'N/A'}) {
	return `${born} ${died}`
}


//2-1
movies.map(movies => {
	return `${movie.title) (${movie.year}) is rated ${movie.score}`
})
//2-2
movies.map(({title, score, year}) => {
	return `${title) (${year}) is rated ${score}`
})

class 문법

//파라미터 활용법
function 기계(i){
	this.name = i;
}
var a = new 기계(kim);

//최근 class 문법
class 기계 {
	constructor(i){
    	this.name = i;
}     
new 기계();

defer

<head>
	<script defer src="main.js"></script>
</head>

rest parameter & forEach

function printAll(...args) {
	for (let i = 0; i <args.length; i++) {
    	console.log(args[i]);
	}
    
    for (const arg of args) {
    	console.log(arg);
	} //이런 식으로 간단하게 출력할 수 있다
    
    args.forEach(arg) => console.log(arg));
}
printAll('dream','coding','ellie');

DOM

getElementBy(Id,TagName,ClassName)

cosnt allImages = document.getElementByTagName('img');
for (let img of allImages) {
	console.log(img.src)
}

properties & methods

const liS = document.querySelectorAll('li');
for(let li of liS){
    li.classList.toggle('highlight');
}

append

for (let i =0; i <100; i++) {
	const newB = document.createElement("button");
    newB.innerText="Hey";
    const container = document.querySelector("#container");
    container.appendChild(newB);
}

addEventListener

const btn3 = document.querySelector('#v3');
btn3.addEventListener('mouseup',function() {
	alert("Clicked")
})

preventDefault

📣 자바스크립트 기초 강의: 06-08

class vs object

class = fields + (methods)

javascript class

introduced in ES6
syntactical sugar over prototype-based inheritance

property를 priviate 하게 만든다 -> incapsulation

getter & setter

class User {
	constructor(firstName, lastName, age) {
    	this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
}
// getter 설정하는 순간 this.age는 메모리에 있는 데이터 불러오는 것 아닌 getter 호출함
get age() {
	return this._age;
}
// setter 정의하는 순간 = age; 호출할 때(값을 할당할 때) 메모리의 값 할당하는 것 아닌
// setter을 호출하게 된다 
// 즉 setter 안에서 전달된 값을 할당할 때 메모리의 값 할당하는 것이 아니라 세터 호출
// setter 안에서 값 할당하고 호출하는 게 무한정 반복되면 콜스택이 꽉 차는 에러 발생 
// 따라서 게터와 세터 안의 변수의 이름을 _age로 설정한 것
// 이렇게 유저 클래스 안에는 세 개의 필드 존재: firstName, lastName, _age
set age(value) {
	if (value < 0) {
    	throw Error('age can not be negative');
        }
	this._age = value < 0 ? 0 : value;
}

const user1 = new User('steve','job',-1);
console.log(user1.age);

fields (public, private)

너무 최근에 나온 것

class Experiment {
	publicField = 2; //외부에서 접근 가능 
    #privateField = 0; //클래스 내부에서만 값이 읽고 접근 변경 가능 
}
const experiment = new Experiment();
console.log(experiment.publicField); //2
console.log(experiment.privateField); //undefined 

static properties and methods

너무 최근

원래 클래스 안의 필즈와 메소드는 새로운 오브젝트를 만들 때마다 그대로 복제되어 값만 지정된 값으로 변경되어 만들어진다.
간혹 오브젝트, 데이터에 상관 없이 클래스가 가지고 있는 고유한 값과 데이터에 상관없이 동일하게 반복적으로 사용되는 메소드가 있다.
static은 object에 상관없이 클래스 자체에 연결되게 된다.

class Article {
	static publisher = 'Dream Coding';
    constructor(articleNumber) {
    	this.articleNumber = articleNumber;
	}

	static printPublisher() {
    	console.log(Article.publisher);
    }
}

const article1 = new Article(1);
const article1 = new Article(2);
console.log(article1.publisher); //undefined
//static 안 썼다면 원래는 오브젝트의 퍼블리셔에 접근해서 출력 가능함 
//static을 쓰면 오브젝트마다 할당되는 게 아니라 Article이라는 클래스 자체에 붙는다
console.log(Article.publisher);
Aritcle.printPublisher();
//메모리의 사용을 줄여준다

상속(Inheritance) & 다양성

공통점, 한 번에 정의 후 속성값을 재사용, 유지 보수에 쉽다
a way for one class to extend another class.

// 세 개의 필드, 두 개의 메소드 
class Shape {
	constructor(width, height, color) {
    	this.width = width;
        this.height = height;
        this.color = color;
	}
    
    draw() {
    	console.log(`drawing ${this.color} color of');
	}
    
    getArea() {
    	return this.width * this.height;
	}
}
// shape의 모든 것들이 rectangle에 포함되게 된다 -> 이렇게 계속 동일한 것 재사용
class Rectangle extends Shape {}
// 다양성, 필요한 함수만 재정의해서 쓸 수 있다 - overriding
class Triangle extends Shape {
	draw() {
    	super.draw();
        //부모의 draw함수 호출로 부모의 메소드도 호출될 수 있음
    	console.log('▲');
	}
 	getArea() {
    	return (this.width * this.height)/2;
	}
}

const rectangle = new Rectangle(20,20,'blue');
rectangle.draw();
console.log(rectangle.getArea());
const triangle = new Triangle(20,20,'blue');
triangle.draw();
console.log(triangle.getArea());

instanceOf

오브젝트가 클래스의 인스턴스인지, 오브젝트가 클래스 이용해서 만들어진 오브젝트인지

t, f, t, t, t
자바스크립트에서 만든 모든 오브젝트 클래스들은 자바스크립트에 있는 오브젝트를 상속한 것
-> 어떤 오브젝트든지 공통적으로 존재하는 메소드를 쓸 수 있다는 뜻

🔸 오브젝트 클릭+ cmd -> 정의된 부분 보여줌

MDN 자바스크립트 레퍼런스

object

literals and properties

one of the javascript's data types
a collection of related data and/or functionality
Nearly all objects in Javascript are instance of Object
object = { key : value };, key(프로퍼티)와 그 프로퍼티가 가지고 있는 값

데이터 관리, 로지컬하게

function print(person) {
	console.log(person.name);
    console.log(person.age);
}

const ellie = { name: 'ellie', age: 4 };
print(elllie);

//오브젝트 만드는 방법 두 가지
const obj1 = {}; //'object literal' syntax
const obj2 = new Object(); //클래스 템플릿을 이용해서 //'object constructor' syntax

//자바스크립트는 dynamically type laguage, 동적으로 타입이 runtime에 결정된다 
//ellie.hasJob = true;
//그래서 이런 가능하지만 미친 짓 가능, 유지보수 힘들고 에러 발생 가능성 다분 

//delete ellie.hasJob;
//이것도 가능하지만 하지 마 

computed properties

//object의 data에 접근하는 방법
console.log(ellie.name); //dot 문법 활용
//키에 해당하는 값을 받아오고 싶을 때
console.log(ellie['name']) //프로퍼티, 키를 스트링 타입으로 접근
//실시간으로 원하는 키의 값을 받아올 때 씀 
//어떤 키가 정확하게 필요한 지 모를 때, 런타임에서 결정될 때 

function printValue(obj, key) {
	console.log(obj[key]);
}
print(ellie, 'name');
print(ellie, 'age');
//언제 어떤 key를 받아오고 어떤 key를 출력할 지 코딩하는 시점에서 모름
//object에 key라는 프로퍼티 들어있는지 모름

property value shorthand

const person = makePerson('ellie',30);
function makePerson(name, age) {
	return {
    	name,
        age,
	};
}
console.log(person);
//shorthand 덕분에 name:name으로 안 써도 됨 (key와 value의 이름이 동일하다면)

constructor function

//보통 계산하지 않고 순수하게 오브젝트를 생성하는 함수들은 다음과 같이 쓴다
//대문자로 시작하는 함수명
const person = new Person('ellie',30);
function Person(name, age) {
	//this = {};, (오브젝트)
	this.name = name;
    this.age = age;
	//return this;
}

in operator

property existence check (key in obj)

console.log('name' in ellie);

for..in vs for..of

유용하게 쓸 수 있음

//모든 키를 받아와서 출력
//for (key in obj)
for (key in ellie) {
	console.log(key);
}    

//배열 리스트, 순차적, iterable한 값
//for (value of iterable)
const array = [1,2,4,5];
//이전 방식
for (let i = 0; i < array.length; i++) {
	console.log(array[i]);
}
//쉽게 쓰는 방법
for (value of array) {
	console.log(value);
}

cloning

//Objcet.assign(dest, [obj1, obj2, obj3...])
const user = { name: 'ellie', age: '20' };
const user2 = user;
//user가 메모리의 reference를 가리키고 있다 
//user에 있는 reference의 값이 user2에도 동일하게 할당된다 
//user2가 가리키고 있는 reference도 동일한 오브젝트를 가리키고 있다 

user2.name = 'coder';
console.log(user); // { name: 'coder', age: '20' }

//그렇다면 이런 식으로 말고 진짜 오브젝트를 복제할 수 있는 방법은?
//old way 
const user2 = {};
for (key in user) {
	user3[key] = user[key];
//user3에 새로운 프로퍼티인 name을 추가 = 값은 기존 user의 이름에 있는 값
}
console.log(user3);

//new way
//Object는 기본적으로 자바스크립트에 탑재돼 있는 오브젝트이고 모든 오브젝트가 이를 상속
//command+클릭으로 확인하면 설명 나옴
//assign<T,U> (targe: T, source: U): T & U;
const user4 = {};
Object.assign(user4, user);
console.log(user4);

//더 간결하게 리턴값 작성
const user4 = Object.assign({}, user);

//another example
const fruit1 = { color: 'red' };
const fruit2 = { color: 'blue', size: 'big' };
const mixed = Object.assign({}, fruit1, fruit2);
console.log(mixed.color); //blue
console.log(mixed.size); //big
//뒤에 나오는 애가 앞에 프로퍼티의 값을 덮어씌우기 때문

-> 객체지향 더 알아보고 싶다면 자바 공부

배열(array)

참고링크: 드림코딩

비슷한 종류의 데이터를 묶어서 보관 : 자료구조

오브젝트와 자료구조의 차이

토끼와 당근 오브젝트는 각각의 특징들이 있다
토끼는 동물, 귀 두 개라는 프로퍼티, 먹는다라는 메소드(함수) 있음
당근은 비타민씨와 주황색이라는 프로퍼티만 있음
자료구조는 비슷한 오브젝트끼리, 토끼는 토끼끼리 당근은 당근끼리 묶어놓는 것

다른 언어에서는 자료구조에 동일한 타입의 오브젝트만 담을 수 있다
하지만 자바스크립트는 dynamically typed language
따라서 한 자료구조 안에 다양한 종류의 오브젝트를 담을 수 있다
가능하지만 하지 마

이런 자료구조 중에서도 새로운 데이터를 자료구조에 삽입, 삭제, 검색, 정렬할 때
얼마나 효율적으로 할 수 있는지 연구하는 게 알고리즘 공부

배열의 포인트는 인덱스
삽입과 삭제가 편하다

array declaration

배열 선언 방법
배열은 인덱스를 기준으로 데이터가 저장된다

const arr1 = new Array();
const fruits = [🍎,🍌];

index position

console.log(fruits[0]); //첫번째 데이터
console.log(fruits[fruits.length-1]); //마지막 데이터

looping over an array

print all data

//1 for
for (let i = 0; i < fruits.length; i++) {
	console.log(fruits[i]);
}

//2 for of
for (let fruit of fruits) {
	console.log(fruit);
}    

//3 forEach
fruits.forEach(function() {
	console.log('he'); // he he (사과 바나나 두 개니까)
});

fruits.forEach(function(fruit, index, array) {
	console.log(fruit, index, array); 
});
//arrow function
fruits.forEach((fruit) => console.log(fruit));

//forEach는 배열 안에 들어있는 값들마다 내가 전달한 함수를 출력한다 
//fruits의 forEach api를 이용한다, forEach는 콜백 함수를 받아온다
//반드시 cmd+클릭으로 확인해 볼 것 직접 써보면서 배우기 (api 정의된 곳으로 가서 문서 보기)

addition, deletion, copy

//push: add an item to the end
fruits.push('🍓','🍑');
console.log(fruits);

//pop: remove an item from the end
fruits.pop();
console.log(fruits);

//unshift: add an item to the beginning
fruits.pop('🍉','🍇');
console.log(fruits);

//shift: remove an item to the beginning
fruits.pop();
console.log(fruits);

//note!! shift, unshift are slower than pop, push
//전체 배열이 shift되는 operation,기능들은 느릴 수 밖에 없다
//배열의 길이가 길면 길수록 움직여야 되는 게 많기 때문에 더 느림 

//splice: remove an item by index position
fruits.splice(1); //인덱스부터 모든 데이터를 지운다
fiuits.splice(1,1);//인덱스부터 하나만 지운다
fiuits.splice(1,1,'🍒','🍋');//인덱스부터 하나만 지우고 그 자리에 두 개 추가
fiuits.splice(1,0,'🍒','🍋');//지우지 않고 추가

//combine two arrays
cosnt fruits2 = ['🍍','🥭'];
const newFruits = fruits.concat(fruits2); 
//연결, 새로 묶여진 배열이 합해져서 리턴

//searching
//find the index
console.log(fruits.indexOf('🍉')); //어디 있나
console.log(fruits.includes('🍉')); //있나 없나

//lastIndexOf
//indexOf는 제일 첫번째로 해당하는 값을 만나면 그 값이 들어있는 인덱스 리턴 
//lastIndexOf는 맨 마지막의 해당하는 값 인덱스 리턴

array api 직접 가서 보기!

0개의 댓글