wrapper object
Primitive Types(기본타입 == 원시타입)
- string, number, bigint, boolean, undefined, symbol, null ## 객체가 아닌 기본타입이다.
- 기본 타입은 객체가 아님
- 기본 타입은 프로퍼티와 메서드를 정의할 수 없음
- new 키워드를 사용하여 원시 타입을 래퍼 객체로 생성할 수 있지만, 주로 사용하는 방법은 아님
let a = 'apple'
let a = new String('apple')
string -> String
number -> Number
bigint -> Bigint
boolean -> Bollean
symbol -> Symbol
URL, URI(Uniform Resource Identifier)
- 아스키 문자로만 구성되어야 함
- 한글이나 특수문자는 이스키케이프 처리
cosnt URL = 'https://코리아아이티아카데미.com'
const encoded = encodeURI(URL) // 이스케이프 처리
cosnt URL = 'https://코리아아이티아카데미.com'
const decoded = decodeURI(encoded) // 디코드 처리(원래대로)
동등 연산자( === )
- 기본 타입으로 생성된 변수와 new 키워드를 사용하여 명시적으로 생성된 래퍼객체는 서로 다른 타입
'JavaScipt' === 'JavaScipt' // true
'JavaScipt' === new Sring('JavaScipt') // false
10 == new Number(10) // false
let num1 = 10
let num2 = new Number(10)
num1 === num2 // false
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>함수 작성법</title>
</head>
<body>
<h2>함수 작성법</h2>
<script>
// 함수의 기본
function sum(num1, num2){
console.log('sum() 호출!')
return num1+num2
}
const result = sum(10, 3)
console.log(result)
console.log('--------------')
// 함수와 메모리
const add = sum
console.log(sum(10, 3)) // 같은 메모리를 사용하므로, 같은 값이 나옴
console.log(add(10, 3))
console.log('--------------')
// 함수 작성팁
// 조건식이 있을 때, 조건을 만족하지 않는 경우 함수 도입부분에서 함수를 미리 종료
function print(num){
if(num <= 0 ) return
console.log(num)
}
print(10)
print(-5) // 그냥 리턴만시키고, 찍히는 건 없음
console.log('--------------')
// 매개변수의 기본값
// 매개변수의 기본값은 무조건 undefined
// undefined와의 연산은 NaN
// arguments: 함수의 전달된 인수에 해당하는 Array 형태의 객체
function total(num1=0, num2=0){
console.log(num1) // 0
console.log(num2) // 0
console.log('arguments: ', arguments)
console.log('arguments[1]: ', arguments[1]) // arguments[1]: undefined
return num1+num2
}
console.log(total()) // NaN
console.log(total(10, 3))
console.log('--------------')
// 콜백 함수
const calc_add = (a, b) => a+b
const calc_multiply = (a, b) => a*b
console.log(calc_add(10, 5))
console.log(calc_multiply(10, 5))
function calculater(num1, num2, action){ // action은 함수를 받을 곳
if(num1 < 0 || num2 < 0) return // 걸러낼거 있으면 먼저 걸러내라
const result = action(num1, num2)
console.log(result)
return result
}
calculater(4, 2, calc_add) // calc_add의 메모리 주소만 보내면 됨
calculater(4, 2, calc_multiply) // calc_multiply 메모리 주소만 보내면 됨
console.log('--------------')
// 문제.
// 특정 숫자를 입력하면 해당 숫자까지를 출력 함수
// 예) 5를 입력하면 1 2 3 4 5를 출력
// 특정 숫자를 입력하면 해당 숫자의 제곱을 출력 함수
// 예) 4를 입력하면 16이 출력
// 위 두개의 식을 함수로 만들고 두 함수의 기능을 모두 사용할 수 있는 iterate() 콜백함수를 만들어보자
// const calc_list.sort(a,b) => {
// if(a>b) return 1
// if(a==b) return 0
// if(a<b) return -1
// }
// const calc_multiply = (a) => a*a
// console.log(calc_list(10, 5))
// console.log(calc_multiply(10, 5))
// function iterate(num1, num2, action){ // action은 함수를 받을 곳
// if(num1 < 0 || num2 < 0) return // 걸러낼거 있으면 먼저 걸러내라
// const result = action(num1, num2)
// console.log(result)
// return result
// }
// calculater(4, 2, calc_list) // calc_add의 메모리 주소만 보내면 됨
// calculater(4, 2, calc_multiply) // calc_multiply 메모리 주소만 보내면 됨
function list(num){
for(let i=1; i<=num; i++){
console.log(i)
}
}
function square(num){
console.log(num**2)
}
function iterate(num, action){
action(num)
}
iterate(5, list)
iterate(3, square)
console.log('--------------')
// 원시값과 객체값의 비교
// 원시값: 값에 의한 복사
// 객체값: 참조에 의한 복사(메모리 주소)
function display(num){
num = 10
console.log(num)
}
const value = 5
display(value) // 10
console.log(value) // 5
function displayObj(obj){
obj.age=13 // 객체의 값을 변경하는 것은 좋지 못함 🤢🤢
console.log(obj)
}
console.log('--------------')
const dog={name:'루시', age: 14} // 원래 전체 메모리에 있는 값을 변경하는데에 사용하는 것은 비추천
// displayObj(dog)
console.log(dog)
function changeAge(obj){
return { ...obj, age: 13} // ...은 obgect를 복사한다는 뜻
}
dog2 = changeAge(dog)
console.log(dog2)
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>객체 활용법</title>
</head>
<body>
<h2>객체 활용법</h2>
<script>
let dog = {
name: '루시',
age: 14,
'dog-weight': 3.5, // 특수문자로 지정하고 싶으면 따움표를 사용해서 지정하자
['dog-height']: 0.8 // 혹은 대괄호를 사용하자
}
console.log(dog.name)
console.log(dog['age'])
dog.family = '포메라니안' //프러퍼티를 추가
console.log(dog.family)
console.log(dog['family1'])
delete dog['dog-height'] // undefined
console.log(dog['dog-height']) // undefined
console.log('---------------')
// 동적으로 속성에 접근하기
function getValue(obj, key){
// dog.name
return obj[key]
}
console.log(getValue(dog, 'name')) // 루시
function addKey(obj, key, value){
obj[key] = value
}
addKey(dog, 'dog-height', 0.7)
console.log(dog) // {name: '루시', age: 14, dog-weight: 3.5, family: '포메라니안', dog-height: 0.7}
function deleteKey(obj, key){
delete obj[key]
}
deleteKey(dog, 'dog-height')
console.log(dog) // {name: '루시', age: 14, dog-weight: 3.5, family: '포메라니안'} # dog-height: 0.7이 날라감
console.log('---------------')
// 객체 생성 함수 만들기
const x=0
const y=0
const coord = {x, y}
console.log(coord) // {x: 0, y: 0} # [[Prototype]]:Object
function makeObj(name, age){
return {name, age}
}
console.log(makeObj('apple', 20)) // {name: 'apple', age: 20} name, age는 key이고 apple 20은 값
console.log('---------------')
const apple = {
name: 'apple',
display: function(){
console.log(`${this.name}: 🍓`)
}
}
const lemon = {
name: 'lemon',
display: function(){
console.log(`${this.name}: 🍋`)
}
}
console.log(apple) // {name: 'apple', display: ƒ}
apple.display() // apple: 🍓
console.log(lemon) // {name: 'lemon', display: ƒ}
lemon.display() // lemon: 🍋
console.log('---------------')
// Fruit 생성자를 만들고 위와 같은 결과를 동일하게 출력할 수 있는 객체를 만들어 출력해보자.
// 단, Fruit(name, emoji) 형태로 만든다.
// const Fruit(name, emoji) = {
// Fruit.name: (`${this.name}`),
// Fruit.display: function(){
// console.log(`${this.name}: 🍓`)
// }
// }
// const lemon = {
// name: 'lemon',
// display: function(){
// console.log(`${this.name}: 🍋`)
// }
// }
function Fruit(name, emoji){
this.name = name
this.emoji = emoji
this.display = () => {
console.log(`${this.name}: ${this.emoji} `)
}
}
const apple2 = new Fruit('apple', '🍓')
const lemon2 = new Fruit('lemon', '🍋')
console.log(apple2) // Fruit {name: 'aple', emoji: '🍓', display: ƒ}
apple2.display() // apple: 🍓
console.log(lemon2) // Fruit {name: 'lemon', emoji: '🍋', display: ƒ}
lemon2.display() // lemon: 🍋
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>클래스 심화</title>
</head>
<body>
<h2>클래스 심화</h2>
<script>
// static
// 정적 프로퍼티 및 메소드를 생성(new처럼 생성시기를 마음대로 조절 가능:동적, 시기를 정할 수 없고 미리 정해진 크기를 프로그램이 실행되면 올라가는 것)
// 클래스 레벨 static을 사용한 메소드에서는 this를 참조할 수 업슴. 메모리를 먼저 올라가기 때문에 같이 올려놓을 수 없음
class Fruit {
static count_fruits = 10 // this를 쓰지 않음. 객체를 만들면 그 메모리 주소를 만듬 먼저 메모리에 올라갔기 때문에, this를 활용할 수 없음
constructor(name, emoji){
this.name = name
this.emoji = emoji
}
display = () => {
console.log(`${this.name}: ${this.emoji} `)
}
static makeBanana(){
return new Fruit('banana', '🍌')
}
}
const apple = new Fruit('apple', '🍓')
const lemon = new Fruit('lemon', '🍋')
console.log(apple) // Fruit {name: 'apple', emoji: '🍓', display: ƒ}
console.log(apple.name) // apple
console.log(lemon) // Fruit {name: 'lemon', emoji: '🍋', display: ƒ}
console.log(lemon.name) // lemon
console.log(Fruit.count_fruits) // 10
const banana = Fruit.makeBanana()
console.log(banana) // Fruit {name: 'banana', emoji: '🍌', display: ƒ}
console.log('----------------------------')
class Dog { // 객체 지향프로그램에서는 프러퍼티를 직접접근하면 문제가 생길 수 있음
#name
#color // private되어 있는 변수들은 접근이 불가능하고,
constructor(name, color){
this.#name = name
this.#color = color
}
// 프러퍼티명과 꼭 일치할 필요는 없음 // set을 이요해서, 해당값을 직접 넣는다.
set name(value){
console.log('set', value)
this.#name = value
}
get name(){
return `이름:${this.#name}`
}
run = () => {
console.log(`${this.#color} 색상의 강아지 ${this.#name}가 달립니다.`)
}
#eat = () => {
console.log(`${this.#name}는 먹습니다.`)
}
myEat = () => {
this.#eat() // 프라이빗한 메소드는 내부에서 사용불가하므로, 다른 메소드에서 불러오고 출력
}
}
const Rucy = new Dog('루시', 'white')
console.log(Rucy) // Dog {name: '루시', color: 'white'}
// Rucy.name = '류씨' // 여기의 name은 새로만들어져서 저장되고, 실제로 쓰는 변수는 아님
// Uncaught SyntaxError: Private field '#name' must be declared in an enclosing class
// Rucy.#name = '류씨'
console.log(Rucy) // Dog {name: '류씨', color: 'white'}
Rucy.name = '류씨'
console.log(Rucy) // Dog {#name: '류씨', #color: 'white'}
console.log(Rucy.name) // 이름:류씨 // 해당 프러퍼티명처럼 불러주면됨
Rucy.run() // white 색상의 강아지 류씨가 달립니다.
// Rucy.eat() // Uncaught TypeError: Rucy.eat is not a function
Rucy.myEat() // 류씨는 먹습니다.
console.log('----------------------------')
// 문제.
// 카운터 만들기
// 카운터를 0으로 값을 초기화 한 뒤 하나씩 숫자를 증가할 수 있는 메소드를 구현
class Counter {
#value
constructor(value){
if(isNaN(value) || value<0) { // 숫자가 아니면 true
this.#value = 0
}else{
this.#value = value
}
}
get value(){
return this.#value
}
increment = () => {
this.#value++
}
}
const cnt = new Counter(0)
console.log(cnt.value)
cnt.increment() // 1
cnt.increment() // 2
console.log(cnt.value)
// 문제부분 다시 보기
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>상속의 활용</title>
</head>
<body>
<h2>상속의 활용</h2>
<script>
class Animal {
constructor(color){
this.color = color
}
eat() {
console.log('먹는다!')
}
sleep() {
console.log('잔다!')
}
}
class Dog extends Animal {
play(){
console.log('논다!')
}
}
const Rucy = new Dog('white')
console.log(Rucy) // Dog
Rucy.eat() // 먹는다!
Rucy.sleep() // 잔다! // 부모의 메소드를 그대로 활용할 수 있음, 상속받음
Rucy.play() // 논다!
console.log('----------------------------')
class Cat extends Animal{ // Animal 의 기능을 상속받자
constructor(color, name){
super(color)
this.name = name
}
// 오버라이딩
eat(){
console.log('맛있게 먹는다!')
}
}
const Horang = new Cat('black', '호랑이')
console.log(Horang) // Cat {color: 'balck', name: '호랑이'}
Horang.eat() // 맛있게 먹는다!
console.log('----------------------------')
// 문제.
// 정직원, 알바를 나타낼 수 있는 클래스를 생성
// FullTimeEmployee, PartTimeEmployee
// 직원의 정보는: 이름, 부서명, 한달 근무 시간
// 급여: 정직원(2만원), 알바(1만원)
// 매달 직원들의 정보를 이용해서 한달 급여를 계산하는 메소드를 구현 (calculatePay())
// 예) kim.calculatePay() -> 한달 급여
class Employee {
constructor(name, department, hoursPerMonth, payRate){
this.name = name
this.department = department
this.hoursPerMonth = hoursPerMonth
this.payRate = payRate
}
calculatepay(){
return this.hoursPerMonth * this.payRate
}
}
class FullTimeEmployee extends Employee{ // extends는 상속받다
static PAY_RATE = 20000
constructor(name, department, hoursPerMonth){
super(name, department, hoursPerMonth,
FullTimeEmployee.PAY_RATE)
}
}
class PartTimeEmployee extends Employee{ // extends는 상속받다
static PAY_RATE = 10000
constructor(name, department, hoursPerMonth){
super(name, department, hoursPerMonth,
PartTimeEmployee.PAY_RATE)
}
}
const Kim = new FullTimeEmployee('김사과', '개발자', 160)
const Oh = new PartTimeEmployee('김사과', '디자이너', 100)
console.log(Kim.calculatepay())
console.log(Oh.calculatepay())
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Wrapper</title>
</head>
<body>
<h2>Wrapper</h2>
<script>
const num = 10 // number 원시타입
console.log(typeof(num)) // number
console.log(num.toString()) // 10
console.log(typeof(num.toString())) // string
console.log(typeof(num)) // number
// 지수 표기법(10의 n승으로 표기)
const x = 102
console.log(x.toExponential()) // 1.02e+2
// 반올림하여 문자열로 변환
const x2 = 1234.12
console.log(x2.toFixed()) // 1234
// 로컬형식의 문자형으로 변환
console.log(x2.toLocaleString('ar-EG')) // ١٬٢٣٤٫١٢ 아랍어로 변환
const x3 = 0.1 + 0.2 - 0.2
console.log(x3) // 0.10000000000000003
console.log(globalThis) // Window {window: Window, self: Window, document: document, name: '', location: Location, …}
// window객체가 찍히는 것은, 웹 에이피아이, javascript가 어는 환경에서 실행되는지 알려줌
const encoded = encodeURI(URL)
const decoded = decodeURI(encoded)
console.log(encodeURIComponent(encodedCom))
</script>
</body>
</html>