javascript setting
전세계의 개발자들이 만든 다양한 기능들을 관리
package.json 생성 (안 되면 새로고침)
node_modules 생성
-D : 개발할 때 필요, 일반 웹페이지 x
설치하면 node_modules에 설치
package.json에 기록
(dependencies, Devdependencies)
node_modules 삭제해도 package.json에 남아있어서 npm i 입력하면 설치
package.json, package-lock.json : 삭제하면 안됨
scripts 기존 내용 삭제
open with live server 대신 사용
main.js
import _(변수) from 'lodash'
추가 : package.json 파일에 있는 lodash 사용
출력 : helloWorld
scripts
개발용 서버 열림
코드 난독화
= index.html 파일을 한줄로 바꿔버림
버전 확인
git에 업로드할 항목 선택
.gitignore 파일 생성
.cache/
(cache 폴더 무시)
Javascript Essential
import getType from './getType'
console.log("Hello world!")
console.log(typeof 123)
console.log(typeof true)
console.log(typeof undefined)
console.log(typeof null)
console.log(typeof {})
console.log(typeof [])
// 전부 object로 나와서 정확한 확인 x
console.log(getType(123))
할당 연산자
const a = 2 // '='이 할당 연산자, 재할당 불가
let a = 2
a = a + 1 // 재할당 가능
a += 1
console.log(a)
비교 연산자
let a = 1
let b = 1
console.log(a === b) // true 일치 연산자
function isEqual(x, y){
return x === y
}
console.log(isEqual(1, 1))
console.log(a !== b) // false 불알치 연산자
논리 연산자
const a = 1 === 1 // a : true
const b = 'AB' === 'AB' // b : true
console.log(a && b) // true and 연산자
console.log(a || b) // true or 연산자
console.log(!a) // false not 연산자
삼항 연산자
console.log(a ? '참' : '거짓') // a가 참이라면 '참', 거짓이라면 '거짓'
Random
import random from './getRandom.js'
switch (a) {
case 0 :
console.log(a)
break
case 1 :
console.log(a)
break
case 2 :
console.log(a)
break
default :
console.log(a)
}
반복문
const ulEl = document.querySelector('ul')
console.log(ulEl)
for (let i = 0; i < 3; i++){
const li = document.createElement('li') // 메모리상 li 태그를 li 변수에 연결
li.textContent = `list-${i+1}` // ${} : 표현식 삽입, li의 글자 내용으로 1,2,3,4 출력
if ((i+1) % 2 === 0) { // 짝수번째에서만 실행, i가 아닌 i + 1로 설정해야함
li.addEventListener('click', function () { // click 되었을 경우 textcontent 출력
console.log(li.textContent)
})
}
ulEl.appendChild(li) // ul태그의 자식으로 삽입
}
변수 유효 범위
// var, let, const
function scope() {
if (true) {
const a = 123
}
console.log(a) // let, const 유효범위(block)에서 벗어나있기 때문에 오류 -- block 레벨에서 관리하는게 편함
// var : 함수 범위에서 유효
}
scope()
형 변환
const a = 1
const b = '1'
console.log(a == b) // 형 변환, 동등 연산자
if ('false'){ // true
console.log('123') // 123 출력
}
참 값 vs 거짓 값
//참인 값
True, [], 1, 2, 'false', -12, '-3.14'
//거짓인 값 (이걸 알아야 함)
false, '', null, undefined, 0, -0, NaN // (Not a Number의 약자 : 1 + undefined)
함수
function sum(x, y){ // 함수 선언
return x + y
}
const sum = function (x, y){ // 함수 표현
return x + y
}
arguments 객체
function sum(){
console.log(arguments)
return arguments[0] + arguments[1]
}
console.log(sum(7,3)) // 7과 3이 배열 형태로 들어감
화살표 함수
// () => {} vs function() {}
const double = function (x){
return x * 2
}
const doubleArrow = (x) => {
return x * 2
}
const doubleArrow = x => x * 2
const doubleArrow = x => ({
// x에 배열, 객체 데이터도 가능
// -> 함수의 block을 나타내는 기호도 중괄호로 겹침
// -> undefined로 출력 -> 소괄호 이용
})
즉시 실행 함수 (IIFE)
const a = 7; // 즉시 실행 함수 앞에는 ; 을 붙여서 실행이 끝났다는 것을 알려야함
(function () {
console.log(a * 2)
})();
(function () {
console.log(a * 2)
}())
Hoisting
// 함수 선언부가 유효범위 최상단으로 끌어올려지는 현상
const a = 7;
double()
const double = function() { // 함수 표현 --> 오류 발생
console.log(a * 2)
}
function double() { // 함수 선언 --> hoisting되어 최상단으로 올려짐
console.log(a * 2)
}
타이머 함수
// setTimeout(함수, 시간(ms)) : 일정 시간 후 함수 실행
// setInterval(함수, 시간(ms)) : 시간 간격마다 함수 실행
// clearTimeout() : 설정된 timeout 함수를 종료
// clearInterval() : 설정된 interval 함수를 종료
setTimeout(function (){
console.log('HUSTLE')
}, 3000)
setTimeout(() => { // 화살표 함수 사용
console.log('HUSTLE')
}, 3000)
const timer = setTimeout(() => { // setTimeout 에서 timer 정보를 반환하는데, 이것을 timer 변수에 저장
console.log('HUSTLE')
}, 3000)
const h1El = document.querySelector('h1')
h1El.addEventListener('click', () => {
clearTimeout(timer) // 저장한 timer 정보를 clearTimeout에 넣음
})
const timer = setInterval(() => { // Interval
console.log('HUSTLE')
}, 3000)
const h1El = document.querySelector('h1')
h1El.addEventListener('click', () => {
clearSelector(timer)
})
콜백
// 함수의 인수로 사용되는 함수
function timeout() {
setTimeout(() => {
console.log('HUSTLE')
}, 3000);
}
timeout()
console.log('MAMBA') // MAMBA 출력 후 3초 뒤 HUSTLE 출력
function timeout(cb) {
setTimeout(() => {
console.log('HUSTLE')
cb()
}, 3000);
}
timeout(() => {
console.log('MAMBA')
})
// () => {
// console.log('MAMBA')
// }
// 함수가 함수의 "인수" (cb, call back)로 들어감
생성자 (class)
const hustle24 = { // {}, [], () : 리터럴
firstName : 'J', // first, lastName : 속성 (멤버)
lastName : 'SH',
getFullName : function() { // getFullName : Method (멤버)
return `${hustle24.firstName} ${this.lastName}`
// backtick 기호 사용 -> 내부 : 보간
// this = hustle24
}
}
console.log(hustle24)
function User(first, last){ // 생성자함수 : camelCase가 아닌 PascalCase로 바꿔줌
this.firstName = first,
thist.lastName = last
}
User.prototype.getFullName = function () { // 통일해야 효율적으로 처리됨
return `${this.firstName} ${this.lastName}` // user의 prototype함수에 getFullname이라는 속성을 부과
}
const hustle24 = new User('J', 'SH') // new : 생성자 선언, User : 생성자 함수
const hustle25 = new User('J', 'SH2') // hustle24 : 생성자 함수의 instance(인스턴스)
const hustle26 = new User('J', 'SH3') // 그때 그때 다른 내용이 들어오기 때문에 통일하기 어려움
console.log(hustle24.getFullName()) // getFullName을 참조함
console.log(hustle25.getFullName())
console.log(hustle26.getFullName())
//javascript : prototype 기반의 언어
this
// 일반 함수는 호출 위치에 따라서 this 정의
// 화살표 함수는 자신이 선언된 함수 범위에서 this 정의
// 예제 0
const shstl24 = {
name: 'shstl',
normal: function () {
console.log(this.name) // 제대로 출력
},
arrow: () => {
console.log(this.name) // undefined 출력
// 선언된 함수 범위 (여기에서는 없음)
}
}
shstl24.normal() // (호출 위치에 따라서 this 정의) this => shstl24
shstl24.arrow()
//예제 1
const shstl25 = {
name: 'MAMBA',
normal: shstl25.normal, // shstl24의 normal함수가 shstl25의 normal 함수에 할당됨
arrow: shstl25.arrow // arrow뒤에 ()가 없음 -- 할당
}
shstl25.normal() // (호출 위치) this = shstl25
shstl25.arrow() // undefined 출력
// 예제 2
function User(name){
this.name = name
}
User.prototype.normal = function(){
console.log(this.name)
}
User.prototype.arrow = () => {
console.log(this.name)
}
const shstl24 = new User('Shstl')
shstl24.normal() // 호출위치 -> shstl24 = this -> Shstl 출력
shstl24.arrow() // 함수 범위가 없기 때문에 undefined 출력
// 예제 3
const timer = {
name: "shstl",
timeout: function() {
setTimeout(function(){ // setTimeout 함수 안에 this가 포함된 함수가 들어감
console.log(this.name) // call back에 의해 setTimeout 함수 어딘가에서 실행 -> undefined 출력
}, 2000)
}
}
timer.timeout()
// 예제 4
const timer = {
name: "shstl",
timeout: function() {
setTimeout(() => { // setTimeout 함수 안에 this가 포함된 함수가 들어감
console.log(this.name) // timeout: function() {~~this~~} 자신이 선언된 함수 범위. = timeout 객체
}, 2000)
}
}
timer.timeout()
ES6 classes
// 사전 지식
const shstl24 = {
name: 'shstl',
normal: function () {
console.log(this.name)
}
}
const shstl24 = {
name: 'shstl',
normal() { // function 부분 생략해도 작동
console.log(this.name)
}
}
// 기존 문법
function User(first, last){
this.firstName = first,
this.lastName = last
}
User.prototype.getFullName = function () {
return `${this.firstName} ${this.lastName}`
}
// ES6 사용 (class 키워드 사용)
class User{
constructor(first, last) { // constructor: function(first, last) 과 동일
this.firstName = first,
this.lastName = last
}
getFullName() { // prototype 을 적지 않아도 됨 -> react에서 자주 사용하는 문법
return `${this.firstName} ${this.lastName}`
}
}
const hustle24 = new User('J', 'SH') // new : 생성자 선언, User : 생성자 함수
const hustle25 = new User('J', 'SH2') // hustle24 : 생성자 함수의 instance(인스턴스)
const hustle26 = new User('J', 'SH3') // 그때 그때 다른 내용이 들어오기 때문에 통일하기 어려움
console.log(hustle24.getFullName()) // getFullName을 참조함
console.log(hustle25.getFullName())
console.log(hustle26.getFullName())
상속
class Vehicle {
constructor(name, wheel){
this.name = name
this.wheel = wheel
}
}
const myVehicle = new Vehicle('운송 수단', 2)
console.log(myVehicle)
class Bicycle extends Vehicle {
constructor(name, wheel) {
super(name, wheel) // super함수는 Vehicle함수의 constructor로 이동
}
}
class Car extends Vehicle {
constructor(name, wheel, license){
super(name, wheel) // super은 Vehicle에서
this.license = license // 확장
}
}
정규 표현식
heropy.blog 참고
regexr.com : 패턴과 일치하는 부분을 찾아줌
npm i parcel-bundler@1.12.3 -D : 버전에서 오류가 날 경우 다른 버전 선택
역할
자바스크립트 정규식 생성 방법
//1. 생성자 함수 방식
const regexp1 = new RegExp("^abc") // (표현식)
const regexp2 = new RegExp("^abc", "gi") // (표현식, 플래그)
const regexp2 = new RegExp("[a-z]", "gi")
// [a-z] : a ~ z 까지의 영어 소문자를 검색하는 패턴
// gi : 일치하는 모든 내용을 다 검색하겠다
// 2. 리터럴 방식
const regexp = /^abc/ // /표현식/
const regexp = /^abc/gi // /표현식/플래그
정규 표현식 활용 예제
const str = 'hello
world'
// 줄바꿈 -> 오류
const str = `hello
world `
// backtik 기호를 사용해야함
const str = `
010-1234-5678
carow7@naver.com
www.naver.com
gonzo dok2
abbcccdddd
`
const regexp = new RegExp('car', '')
console.log(str.match(regexp))
// 출력 : '0 : car' - 처음 발견된 car만 배열로 만들어짐
const regexp = new RegExp('car', 'g')
console.log(str.match(regexp))
// g 옵션: 모든 car을 찾아서 배열로 만들어줌
// gi 옵션 : 대소문자 구분없이 모두 찾음
// 정규 표현식으로 활용
const regexp = /the/gi
console.log(str.match(regexp))
정규표현식을 다루는 다양한 메소드
메소드 | 문법 | 설명 |
---|---|---|
test | 정규식.test(문자열) | 일치 여부(Boolean) 반환 |
match | 문자열.match(정규식) | 일치하는 문자의 배열(Array) 반환 |
replace | 문자열.replace(정규식, 대체문자) | 일치하는 문자들 대체 |
const regexp = /carow/gi
console.log(regexp.test(str))
// 출력 : true
console.log(str.replace(regexp, 'gonzo'))
// replace되어서 출력 but 원본을 변형시키지는 않음
// 원본을 변형시키는 방법
// const str --> let str
// str = str.replace(regexp, 'gonzo')
플래그 (옵션)
플래그 | 설명 |
---|---|
g | 모든 문자 일치 (global) |
i | 영어 대소문자를 구분 않고 일치(ignore case) |
m | 여러 줄 일치 (multi line) |
const str = `
010-1234-5678
carow7@naver.com
https://www.naver.com/frozen
gonzo dok2 fox
abbcccdddd
http://www.google.com
동해물과 백두산이 마르고
`
console.log(str.match(/carow/gi))
// 정규표현식을 리터럴로 선언해도 무관
console.log(str.match(/\./gi))
// '.' 혼자 있으면 다른 기능을 함
// \ : escape character (이스케이프 문자) - 본래의 기능에서 벗어나 상태가 바뀌는 문자
// str에 있는 .을 모두 return
console.log(str.match(/\./gim))
// 각 문장의 끝에 .이 있는지 match
// 출력 : . 하나 return
패턴(표현)
패턴 | 설명 |
---|---|
^ab | 줄(Line) 시작에 있는 ab와 일치 |
ab$ | 줄(Line) 끝에 있는 ab와 일치 |
. | 임의의 한 문자와 일치 |
a|b | a 또는 b와 일치 |
ab? | b가 없거나 b와 일치 |
console.log(str.match(/\.$/gi))
// 의미 : str 끝에 (backtik 기호 직전)에 .이 있는지 match
// 출력 : null
console.log(str.match(/./g))
// 모든 문자와 일치하여 존재하는 모든 문자를 return
console.log(str.match(/\.$/gi))
// 의미 : str 끝에 (backtik 기호 직전)에 .이 있는지 match
// 출력 : null
console.log(str.match(/d$/gm))
// 각 문장의 끝에 d가 있는 경우 d return
console.log(str.match(/^d/gm))
// 각 문장의 처음에 d가 있는 경우 d return
console.log(str.match(/h..p/gmi))
// http인 문자를 return
console.log(str.match(/car|ow7/g))
// car과 ow7 모두 return
console.log(str.match(/car|ow7/))
// g가 없기 때문에 먼저 찾은 값(car)만 return
console.log(str.match(/https?/))
// http는 있지만 s는 있을 수도 있고 없을 수도 있음
// 출력 : https, http
패턴 | 설명
--|--
{3} | 3개 연속 일치
{3,} | 3개 이상 연속 일치
{3, 5} | 3개 이상 5개 이하 연속 일치
console.log(str.match(/d{2}/))
// 출력 : dd
패턴 | 설명 |
---|---|
[abc] | a또는 b또는 c |
[a-z] | a부터 z 사이의 문자 구간에 일치(영어 소문자) |
[A-Z] | A부터 Z 사이의 문자 구간에 일치(영어 대문자) |
[0-9] | 0부터 9사이의 문자 구간에 일치(숫자) |
[가-힣] | 가부터 힣 사이의 문자 구간에 일치(한글) |
console.log(str.match(/[fox]/g))
// f 혹은 o 혹은 x 가 있는 것을 모두 return
console.log(str.match(/[0-9]{1,}/g))
// 한개 이상이 연속되는 숫자들을 찾음
// 출력 : 010, 1234, 5678
console.log(str.match(/[가-힣]{1,}/g))
// 출력 : 동해물과, 백두산이, 마르고
패턴 | 설명 |
---|---|
\w | 63개 문자(Word, 대소영문 52개, 숫자 10개 + _)에 일치 |
\b | 63개 문자에 일치하지 않는 문자 경계(Boundary) |
\d | 숫자(digit)에 일치 |
\s | 공백(Space, Tab)에 일치 |
console.log(str.match(/\w{2,3}/))
// 숫자를 포함한 영어 알파벳이 2이상 3이하인 것
console.log(str.match(/\b\w{2,3}\b/g))
// \b : 경계를 의미함
// 출력 : 010, com, www 등등
console.log(str.match(/\b/g))
// 글자와 글자 사이, -, \n 등 \w 외의 글자를 전부 return
console.log(str.match(/\bf\w{1,}\b/g))
// boundary 사이에 있는 f로 시작하는 1개 이상의 문자열 return
// 출력 : frozen, fox
console.log(str.match(/\d/g))
// 출력 : 모든 숫자
console.log(str.match(/\d{1,}/g))
// 출력 : 010, 1234, ...
console.log(str.match(/\s/g))
// 공백 문자
// 출력 : 문자열 안에 있는 모든 공백 문자(줄바꿈, 띄어쓰기)
const h = ` the hell o wor l d
!
`
console.log(h.replace(/\s/g, ''))
// 출력 : thehelloworld!
패턴 | 설명
--|--
(?=) | 앞쪽 일치(Lookahead)
(?<=) | 뒤쪽 일치(Lookbehing)
console.log(str.match(/.{1,}(?=@)/g))
// @ 앞에 있는 문자를 전부 찾음
// 1개 이상인 문자를 찾음
// @은 아무런 기능이 없기 때문에 굳이 \@ 을 할 필요가 없음
// 출력 : carow7
console.log(str.match(/(?<=@).{1,}/g))
// 뒤쪽 일치이기 때문에 .{1,}이 뒤에 붙어야함
// 출력 : naver.com
Javascript Level Up
STRING
// indexOf : 호출한 String 객체에서 주어진 값과 일치하는 첫번째 인덱스를 반환
const paragraph = "abc deg ghi"
const term = "deg"
const answer = paragraph.indexOf(term) // paragraph : String 객체, answer = 4
const answer = "abc deg ghi".indexOf("deg") // paragraph : String 객체, answer = 4
const str = "Hello, World!"
console.log(str.slice(0,3)) // 0~3번째 글자만 출력
console.log(str.replace(' world!', '')) // text 대체
const str = "seunghw2@naver.com"
console.log(str.match(/.+(?=@)/)[0]) // 출력 : seunghw2
// 정규 표현식
// . : 한 글자
// + : 그 뒤 글자까지 최대한 많이 일치 시키겠다
// (?=@) : @ 앞에 있는 문자들을 일치시킴
const str = ' Hello world! '
console.log(str.trim()) // 공백들이 전부 사라짐
const pi = 3.141592
console.log(pi) // 3.141592
const str = pi.toFixed(2) // 소수점 둘째짜리까지 자름
console.log(str) // 3.14
console.log(typeof str) // string
const integer = parseInt(str) // 전역함수(setTimeout, setInterval 등등)
const float = parseFloat(str) // parse : 분석하다
console.log(integer) // 3
console.log(float) // 3.14
console.log(typeof integer, typeof float) // number number
Math
// 구글에 Math mdn 검색
Math.abs(-12) // 출력 : 12
Math.min(2,8) // 출력 : 2
Math.max(2,8) // 출력 : 8
Math.ceil(3.14) // 출력 : 4 (소수점에서 올림 처리 ceil : 천장)
Math.floor(3.14) // 출력 : 3 (소수점에서 내림 처리)
Math.round(3.5) // 출력 : 4 (소수점에서 반올림 처리)
Math.random() // 출력 : 0~1사이 무작위 값
Array
// 구글에 Array mdn 검색
const array1 = [5, 12, 8, 130, 44]
const found = array1.find(element => element > 10)
// 화살표 함수 (매개변수 1개 - 중괄호 생략, return 생략)
// find의 method에 함수로 들어감 - callback 함수
// true인것만 find
console.log(found) // 출력 : 12
const array1 = [5, 12, 8, 130, 44]
numbers.length // 출력 : 5
[].length // 출력 : 0
const numbers = [1,2,3,4]
const fruit = ['Apple', 'Banana', 'Cherry']
console.log(numbers.concat(fruit)) // 출력 : 두 개의 데이터를 병합하여 출력 (concenate : 사슬같이 잇다)
console.log(numbers) // 1,2,3,4
console.log(fruit) // 'Apple', 'Banana', 'Cherry'
const numbers = [1,2,3,4]
const fruits = ['Apple', 'Banana', 'Cherry']
fruits.forEach(function (element, index, array){
console.log(element, index, array)
})
// forEach : fruits의 개수만큼 callback함수를 반복하여 출력
// element : 'Apple', 'Banana', 'Cherry'
// element : item / fruit 으로 표현 가능 (그냥 매개변수)
// index : 몇번째인지 (i로도 표현 가능)
// array : fruits의 배열 자체 (잘 사용하지 않음)
const numbers = [1,2,3,4]
const fruits = ['Apple', 'Banana', 'Cherry']
const a = fruits.forEach(function(fruit, index){
console.log(`${fruit}-${index}`) // Apple-0 , Banana-1 ... 출력
})
console.log(a) // forEach 함수는 반환되는 값이 없어 undefined 출력
const b = fruits.map(function(fruit,index){
return `${fruit}-${index}`
})
console.log(b) // map함수는 callback에서 반환된 값이 있음
const b = fruits.map(function(fruit,index){
return { // 객체 리터럴 방식
id : index,
name : fruit
}
})
// id : 0, name : Apple
// id : 1, name : Banana
// id : 2, name : Cherry
const b = fruits.map((fruit,index) => ({ // 화살표 함수
id : index,
name : fruit
})
)
Array (2)
//.filter
const numbers = [1,2,3,4]
const fruits = ['Apple', 'Banana', 'Cherry']
const a = numbers.map(number => {
return number < 3 // true, true, false, false
})
console.log(a)
const a = numbers.map(number => number < 3) // 화살표 함수 사용 -- 결과는 동일
const b = numbers.filter(number => { // filter : true인것만 필터링
return number < 3 // [1, 2]
})
console.log(b)
// .find() .findIndex()
const numbers = [1,2,3,4]
const fruits = ['Apple', 'Banana', 'Cherry']
const a = fruits.find(fruit => {
return /^B/.test(fruit) // 정규표현식 : B로 시작하는 단어
})
console.log(a) // 출력 : 'Banana'
const a = fruits.findIndex(fruit => /^B/.test(fruit))
// 정규표현식 : B로 시작하는 단어의 index
// 화살표 함수
console.log(a) // 출력 : 2
// .includes()
const numbers = [1,2,3,4]
const fruits = ['Apple', 'Banana', 'Cherry']
const a = numbers.includes('3') // true
const b = fruits.includes('Diamonds') // false
// .push() .unshift()
// 원본 수정됨 주의!
const numbers = [1, 2, 3, 4]
const fruits = ['Apple', 'Banana', 'Cherry']
numbers.push(5) // 뒤에 데이터 삽입
console.log(numbers) // 출력 : [1, 2, ,3 ,4, 5]
numbers.unshift(0) // 앞에 데이터 삽입
console.log(numbers) // 출력 : [0, 1, 2, ,3 ,4, 5]
// .reverse()
// 원본 수정됨 주의!
const numbers = [1, 2, 3, 4]
const fruits = ['Apple', 'Banana', 'Cherry']
numbers.reverse()
fruits.reverse()
console.log(numbers)
console.log(fruits) // 출력 : ['Cherry', 'Banana', 'Apple']
// .splice()
// 원본 수정됨 주의
const numbers = [1, 2, 3, 4]
const fruits = ['Apple', 'Banana', 'Cherry']
numbers.splice(2, 1) // numbers[2]부터 1개 지움
console.log(numbers)
numbers.splice(2, 0, 999) // numbers[2]에 0개 지우고 999를 넣어라
객체
// .prototype 이 없이 나오는 것 : 정적(static) 메소드
// Object.assign()
// 열거할 수 있는 하나 이상의 출처 객체로부터 대상 객체로 속성을 복사할 때 사용
const target = { a : 1, b : 2} // 대상 객체
const source = { b : 4, c : 5} // 출처 객체
const returnedTarget = Object.assign(target, source) // Object : 전역 객체
console.log(target) // a : 1, b : 4, c : 5
console.log(returnedTarget) // a : 1, b : 4, c : 5
//
const userAge = { // 객체 데이터 1
// key : value
name: 'shstl',
age: 85
}
const userEmail = { // 객체 데이터 2
name: 'shstl',
email: 'carow7@naver.com'
}
const target = Object.assign(userAge, userEmail) // (대상 객체, 출처 객체)
const example = userAge.assign()
const example = userEmail.assign() // 사용 불가능 (실제 객체 데이터 자체에는 사용 불가)
// assign 이라는 메소드는 Object 전역 객체의 prototype으로 만들어져있지 않기 때문.
// Object.assign() --> O
// Object.prototype.assign() --> X
// --> 정적 메소드의 성질 (static method)
console.log(target) // {name: 'shstl', age: 85, email: 'carow7@naver.com'}
console.log(userAge) // {name: 'shstl', age: 85, email: 'carow7@naver.com'}
console.log(target === userAge) // true : 메모리 주소를 이용했기때문에 완전히 동일 (참조형 - {}, [], function)
const a = {k : 123}
const b = {k : 123}
console.log(a === b) // false
const target = Object.assign({}, userAge, userEmail) // 새로운 객체에 추가
const user = {
name: 'shstl',
age: 85,
email: 'carow7@naver.com'
}
const keys = Object.keys(user)
console.log(keys)
console.log(user['Email']) // 출력 : ['name', 'age', 'email'] -- key 출력
const values = keys.map(key => user[key])
console.log(values) // 출력 : ['shstl', 85, 'carow7@naver.com'] -- key 출력
console.log(user[email]) // 출력 : 'carow7@naver.com' , indexing :
const values = keys.map(key => user[key]) // key를 매개변수로 함(편의를 위해 임의로) -- keys의 원소들이 key로 사용 -- keys의 개수만큼 반복
console.log(values) // 출력 : ['shstl', 85, 'carow7@naver.com'] -- key 출력
구조 분해 할당
// = 비구조화 할당
const user = {
name: 'shstl',
age : 24,
email : 'carow7@naver.com'
}
const {name, age, email, address, phone = 'no'} = user // user에 있는 부분이 추출됨
console.log('사용자의 이름은 ${name}입니다') // 정상출력
console.log('사용자의 나이는 ${age}입니다') // 정상출력
console.log('사용자의 이메일은 ${email}입니다') // 정상출력
console.log('사용자의 주소는 ${address}입니다') // undefined
console.log('사용자의 휴대폰 번호는 ${phone}입니다') // no 출력 (기본값)
const fruits = ['Apple', 'Banana', 'Cherry']
const [a, b, c, d] = fruits
console.log(a,b,c,d) // 출력 : Apple, Banana, Cherry, undefined
const [, y] = fruits
console.log(y) // 출력 : Banana
전개 연산자
const fruits = ['Apple', 'Banana', 'Cherry']
console.log(fruits) // 출력 : ['Apple', 'Banana', 'Cherry']
console.log(...fruits) // 출력 : ('Apple', 'Banana', 'Cherry') -- 전개되어 나옴
function toObject(a, b, c){
return{
a : a,
b : b,
c : c
}
}
console.log(toObject(...fruits))
// fruits 가 전개되어 매개변수로 들어감
// 출력
// a : Apple
// b : Banana
// c : Cherry
function toObject(a, ...b){ // 전개 연산자(rest parameter) : a는 a로, 나머지(b, c)는 b로
return{
a : a,
b : b
}
}
const toObject(a, ...b) => ({ a, b}) // 화살표 함수 : 객체 데이터에서는 ({ })로 표현
불변성
- 데이터 불변성// 원시 데이터
// String, Number, Boolean, undefined, null
let a = 1
// [메모리 1]
let b = 4
// [메모리 2]
console.log(a, b, a === b)
// [메모리 1] != [메모리 2]
b = a
// a의 메모리 주소가 b에 할당
// a : 1, b : 1
console.log(a, b, a === b)
// [메모리 1] = [메모리 1]
a = 7
// [메모리 3]
// 기존 메모리가 아닌 다른 메모리와 숫자 값 7 할당
// a : 7, b : 1
console.log(a, b, a === b)
// [메모리 3] != [메모리 1]
let c = 1
// [메모리 1]
// b : 1, c : 1
// 새로 추가된 원시 데이터의 값이 기존에 있다면, 새로 추가되는 것이 아닌 기존의 메모리 할당 (데이터 불변성)
console.log(b, c, b === c)
// [메모리 1] = [메모리 1]
// 참조형 데이터
// Object, Array, Function( callback 함수 -- 참조 S)
// 불변성이 없음 - 가변
let a = { k : 1}
// [메모리 1]
let b = { k : 1}
// [메모리 2]
console.log(a, b, a === b)
// [메모리 1] != [메모리 2]
a.k = 7
// [메모리 1]
b = a
// [메모리 1]
// b.k = 7
console.log(a, b, a === b)
// [메모리 1] = [메모리 1]
a.k = 2
// [메모리 1]
// b.k = 2 같이 변함
// b를 수정해도 a가 변함
console.log(a, b, a === b)
// [메모리 1] = [메모리 1]
let c = b
// [메모리 1]
console.log(a, b, c, a === c)
// [메모리 1] = [메모리 1]
얕은 복사와 깊은 복사
// -복사 X-
const user = {
name: 'shstl',
age : 24
}
const copyUser = user // 같은 메모리 주소 공유
console.log(copyUser === user) // true
user.age = 99 // copyUser도 같이 변함
console.log(copyUser === user) // true
// 얕은 복사
// 전부 복사되는게 아니라 표면만 복사
// 얕은 복사 - 1
const copyUser = Object.assign({}, user)
// 새로운 객체 데이터와 새로운 메모리 주소 할당
// 복사되었기 때문에 서로 영향 x
// 얕은 복사 2
const copyUser = {...user} // 새로운 메모리 주소를 할당받아 user의 속성을 받음 ( '{}' -> 새로운 메모리)
// 얕은 복사와 깊은 복사의 차이
user.name.push('shstl98')
// user.name : 배열 데이터, 참조형 데이터
// user의 객체만 복사한 것, user.name은 복사하지 않았음
// 속성을 복사한게 아님. 속성의 메모리값을 공유.
console.log(user.name === copyUser.name) // 출력 : true
// 깊은 복사
// lodash 추출
import _ from 'lodash'
const copyUser = _.cloneDeep(user) // 깊은 복사
user.name.push('shstl98')
console.log(user.name === copyUser.name) // 출력 : false (복사한 것이기에 동일 메모리 x)
console.log(user) // Array(2) : 하나 추가로 들어감
console.log(copyUser) // Array(1)
가져오기/내보내기
// module : export 위주의 js
import _ from 'lodash' // (from 'node_modules') 기본값 생략
import getType from './getType' // getType.js : 상대경로를 통해 import
import checkType from './getType' // default로 불러오기때문에 getType가 아닌 다른 이름으로 사용 가능
import getRandom from './getRandom' // default로 불러오기때문에 getType가 아닌 다른 이름으로 사용 가능
import { random } from './getRandom' // named export에서는 중괄호 안에 이름을 작성해야함
import { user } from './getRandom' // named export에서는 중괄호 안에 이름을 작성해야함
import { random, user } from './getRandom' // named export에서는 중괄호 안에 이름을 작성해야함
import { user as shstl } from './getRandom' // 객체 분해에서 { user : shstl }과 같은 역할
import * as S from './getRandom' // * : wide card : 한번에 가져올 수 있음
console.log(_.camelCase('hello world!')) // helloWorld!
console.log(getType([1, 2, 3]))
console.log(checkType([1, 2, 3]))
console.log(random(), random())
console.log(user)
console.log(shstl)
console.log(S)
lodash 사용법
import _ from 'lodash'
const userA = [
{ usedId : '1', name : 'shstl'}
{ usedId : '2', name : 'gonzo'}
]
const userB = [
{ usedId : '1', name : 'shstl'}
{ usedId : '3', name : 'Dok2'}
]
const userC = userA.concat(userB) // concat : 중복값 상관없이 모두 병합
console.log('concat', userC)
console.log('uniqBy', _.uniqBy(userC, 'userId')) // 1개일 때 사용
// (중복된 데이터가 있는 배열 데이터, 중복을 보유한 속성)
const userD = _.unionBy(userA, userB, 'userId') // unionBy : 고유값 제외 병합, 2개 이상일 때 사용
console.log('unionBy', userD)
// 예제 2
const users = [
{ userId: '1', name:'Ant'},
{ userId: '2', name:'Bat'},
{ userId: '3', name:'Cat'},
{ userId: '4', name:'Dab'},
{ userId: '5', name:'Ept'}
]
const foundUser = _.find(users, {name : 'Ant'})
const foundUserIndex = _.findIndex(users, {name : 'Ant'})
console.log(foundUser) // 출력 : { userId : "3", name : "Ant" }
console.log(foundUserIndex) // 출력 : 2
_.remove(users, {name : Ant}) // { userId: '1', name:'Ant'} remove 후 출력
console.log(users)
JSON
// 자바스크립트의 객체 표기법
const user = {
name : 'gonzo',
age : '31',
emails : [
'carow7@naver.com',
'seunghw2@gmail.com'
],
'company-name' : 'ILLINAIRE' // '-' 특수 기호가 있기 때문에 key값에 작은 따옴표 사용
}
// <myData.json> 이라고 생각하자
// json 파일은 data를 저장하기 좋은 파일
// json 파일은 하나의 문자 데이터
// 데이터 하나만 담을 수 있음 (아래 예제는 객체 데이터 하나만 담고 있음)
{
"name" : "DOK2",
"age" : 99,
"boolean" : true,
"null" : null,
"object" : {},
"array" : []
}
// <js 파일>
import myData from './myData.json' // .js는 생략 가능했으나 .json은 생략 불가
console.log(myData) // 객체 데이터처럼 출력
const str = JSON.stringify(user) // js -> json
const obj = JSON.parse(str) // json -> js
Storage
// 크롬 >> 개발자도구 >> Applicatioin >> Local Storage, Session Storage
// key, value값이 저장되어 있음
// local storage : 데이터가 만료되지 않음
// session storage : 탭을 닫으면 데이터가 만료됨
localStorage.setItem('cat', 'Dok2')
// key, value(데이터값)
// 하나의 값을 local storage에 추가
// 배열같은 경우 stringify, parse를 거쳐 변환
localStorage.getItem('cat') // 항목 읽음
localStorage.removeItem('cat') // 제거
// 예제 1
const user = {
name : 'gonzo',
age : '31',
emails : [
'carow7@naver.com',
'seunghw2@gmail.com'
],
'company-name' : 'ILLINAIRE' // '-' 특수 기호가 있기 때문에 key값에 작은 따옴표 사용
}
localStorage.setItem('cat', user)
// 제대로 저장 X
// 문자 데이터로 변환해야함
localStorage.setItem('cat', JSON.stringify(user))
localStorage.getItem('cat', user)
// 제대로 동작 X
// js에서 사용할 수 있게 다시 변환해야함
JSON.parse(localStorage.getItem(user))
localStorage.removeItem('user') // 제거됨
// 예제 2
// 저장된 데이터 값 변경
// localStorage 에 데이터가 저장되어있음
const str = localStorage.getItem('user')
const obj = JSON.parse(str)
obj.age = 22
console.log(obj)
localStorage.setItem('user', JSON.stringify(obj))
// cf) lowdb : lodash 를 이용해 storage를 간편하게 사용할 수 있음
OMDB API
// the open movie database
// query string : 검색 문자열
주소?속성=값&속성=값&속성=값
// http://www.omdbapi.com/?apiKey=7035c60c&s=frozen
// json 포맷의 정보를 얻을 수 있음
// js에서 활용하기 위해서는 axios 필요 (http 요청을 처리함)
// npm i axios
import axios from 'axios'
function fetchMovies () {
axios
.get('https://www.omdbapi.com/?apiKey=7035c60c&s=frozen') // http 보다는 https로 요청해야함
.then((res) => {
console.log(res)
const h1El = document.querySelector('h1')
const imgEl = document.querySelector('img')
h1El.textContent = res.data.Search[0].Title
imgEl.src = res.data.Search[0].Poster
})
// method chain : 보기 편하게 줄바꿈 이용
// response(res) : 서버에 get으로 요청하고 나온 응답
// res 데이터의 Array[10] 배열속 첫번째 Search[0]에서 Title 값을 찾아 h1의 내용으로 집어넣음
// res 데이터의 Search[0]에서 Poster값을 imgEl의 src(이미지 링크) 값에 집어넣음
}
fetchMovies()
// npm run dev 를 입력 후 실행