let, const, var
var는 한번 선언된 변수를 다시 선언할 수 있다. | |
var name = 'Mike'; console.log(name); //Mike |
var name = 'Jane'; console.log(name); //Jane |
var는 선언하기 전에 사용할 수 있다. | |
console.log(name); //undefined var name = 'Mike'; |
var name; 호이스팅 console.log(name); //undefined name = 'Mike'; |
변수의 생성과정 | |
var | 1.선언 및 초기화 단계 2.할당 단계 |
let | 1.선언 단계 2.초기화 단계 3.할당 단계 |
const | 1.선언 + 초기화 + 할당 const gender; gender = 'male'; error |
스코프 | |
var | 함수 스코프(function-scoped) |
let, const | 블록 스코프(block-scoped) |
!생성자 함수
객체 리터럴 | let user = { name: 'Mike', age: 30, } |
생성자 함수 | function User(name, age) { 첫 글자는 대문자로 this.name = name; this.age = age; } let user1 = new User('Mike', 30); let user2 = new User('Jane', 22); let user3 = new User('Tom', 17); new 연사자를 사용해서 호출 |
new 함수명(); 호출시 | this = {} return this; 자동으로 반환 및 User 알고리즘 동작 |
메소드 추가 | this.sayName = function() { console.log(this.name); } let user5 = new User('Han', 40); user5.sayName(); // 'Han' |
!객체 메소드(Object methods), 계산된 프로퍼티(Computed property)
계산된 프로퍼티 | let a = 'age'; const user = { name : 'Mike', [a] : 30 // age : 30 } |
Object.assign() : 객체복제 | const newUser = Object.assign({}, user); 매개변수가 빈객체에 병합 newUser.name = 'Tom'; console.log(user.name); // 'Mike' 객체가 서로 다름 Object.assign({ gender:'male' }, user); 프로퍼티 하나 추가 단 키가 같은 프로퍼티면 덮어쒸움 const user = { name : 'Mike' } const info = { age : 20 } .... Object.assign(user, info1, info2) 세개 객체마다 다른 키값이 있는 프로퍼티들을 user에 합쳐짐 |
Object.keys() : 키 배열 반환 | const user = { name : 'Mike'; age : 20, gender : 'male', } Object.keys(user); user객체안에 키들이 배열로 반환 // ["name", "age", "gender"] |
Object.values() : 값 배열 반환 | const user = { name : 'Mike'; age : 20, gender : 'male', } Object.values(user); user 객체안에 값들이 배열로 반환 // ["Mike", 20, "male"] |
Object.entries() : 키/값 배열 반환 | const user = { name : 'Mike'; age : 20, gender : 'male', } Object.entries(user); [ ["name","mike"], ... } 배열로 반환 후 배열로 감싸줌 |
Object.fromEntries() : 키/값 배열을 객체로 | const arr = [ ["name","Mike"], ["age",30], ["gender","male"] ]; Object.fromEntries(arr); { name : 'Mike', ... } 배열에서 객체로 반환 |
심볼(Symbol)
const a = Symbol(); 유일한 식별자 | new를 붙이지 않습니다. |
console.log(a) //Symbol() console.log(b) //Symbol() |
a === b; //false a == b; //false |
const id = symbol('id'); const id2 = symbol('id'); 유일성 보장 id //Symbol(id) id2 //Symbol(id) |
id === id2 //false id == id2 //false |
property key : 심볼형 | const id = Symbol('id'); const user = { name : 'Mike', age : 30, [id] : 'myid' } user //{name: "mike", age: 30, Symbol(id): "myid"} user[id] //"myid" 잘 동작함 |
Object.keys(user); Object.values(user); Object.entries(user); |
["name", "age"] ["Mike", 30] [Array(2), Array(2)] for(let a in user) {} for in 문 사용불가 심볼형은 건너뜀 |
const user = { name: 'Mike', age: 30 } const id = Symbol('id'); user[id] = 'myid'; |
원본 데이터를 건드리지 않고 속성을 추가함 |
Symbol.for() : 전역심볼 const id1= Symbol.for('id'); const id2 = Symbol.for('id'); |
> 하나의 심볼만 보장받을 수 있음 > 없으면 만들고, 있으면 가져오기 때문 > Symbol 함수는 매번 다른 Symbol 값을 생성하지만, > Symbol.for 메소드는 하나를 생성한뒤 키를 통해 같은 Symbol을 공유 id1 === id2; //true Symbol.keyFor(id1) //"id" 변수를 넣어주면 할당한 이름이 가져와짐 |
description | const id = Symbol('id 입니다.'); id.description; //"id 입니다." 전역심볼이 아니면 keyFor을 사용못함 대신 description을 사용하여 이름을 알수있음 |
숨겨진 Symbol key 보는법 | Object.getOwnPropertySymbols(user); //[Symbol(id)] 심볼들만 볼수있음 |
Reflect.ownKeys(user); | ["name", "age", Symbol(id)] 심볼형 키를 포함한 모든 객체에 키를 보여줌 |
Number, Math
let num1 = 5.1; let num2 = 5.7; |
Math.ceil(num1); // 6 Math.ceil(num2); // 6 소주점 상관없이 오름 |
let num1 = 5.1; let num2 = 5.7; |
Math.floor(num1); // 5 Math.floor(num2); // 5 소주점 상관없이 내림 |
let num1 = 5.1; let num2 = 5.7; |
Math.round(num1); // 5 Math.round(num2); // 6 반올림 메소드 |
let userRate = 30.1234; 요구사항 : 소수점 둘째자리 까지 표현(셋째 자리에서 반올림) |
Math.round(userRate * 100) / 100 // 30.12 100을 곱하고 round 반올림후 100을 나눈다 |
let userRate = 30.1234; 요구사항 : 소수점 둘째자리 까지 표현(셋째 자리에서 반올림) |
userRate.toFixed(2); // "30.12" 숫자를 인수로 받아 그 숫자만큼 소수점 이하 계수를 반영 |
let userRate = 30.1234; | userRate.toFixed(2); // "30.12" userRate.toFixed(0); // "30" 소수계수 0 이라 정수만 반영 userRate.toFixed(6); // "30.123400" 소수계수 6이라 뒤에는 0으로 반영 |
let userRate = 30.1234; | userRate.toFixed(2); // "30.12" Number( userRate.toFixed(2)); // 30.12 넘버를 이용해 숫자형으로 바꿔준다 |
let x = Number('x'); // NaN | isNaN(x) // true NaN 확인하는법 |
parselInt() : 정수만 반환 | let margin = '10px'; parseInt(margin); // 10 문자가 뒤에 있으면 앞에 숫자 반환 Number(margin); // NaN let redColor = 'f3'; parseInt(redColor); // NaN 문자가 앞에 있으면 NaN 반환 let redColor = 'f3'; parseInt(redColor); // NaN parseInt(redColor, 16); // 243 16진수로 반환 parseInt('11', 2); // 3 2,10진수로 반환 |
parseFloat() : 소수점 반환 | let padding = '18.5%'; parseInt(padding); // 18 소수점 이하만 반환 parseFloat(padding); // 18.5 소수점까지 반환 |
Math.radom() : 0 ~ 1 사이 무작위 숫자 생성 | Math.random() 메소드를 선언할때 마다 0 ~ 1 사이 숫자 생성 // 0.26484487894564484 |
1 ~ 100 사이 임의의 숫자를 뽑고 싶다면? | Math.floor(Math.random()*100)+1 Math.random() // 숫자를 생성 예시 0.6789 *100 // 100을 곱한다 Math.floor // 소수점 이하를 버린다 내림 67 +1 // 1를 더해줌 floor시 0이 나올 수 있기 때문에 |
Math.max() : 최대값 , Math.min() : 최소값 | Math.max(1, 4, -3, 5, 10, 9, 4.45); // 10 Math.min(1, 4, -3, 5, 10, 9, 4.45); // -3 |
Math.abs() : 절대값 | Math.abs(-1) // 1 |
Math.pow(n, m) : 제곱 | Math.pow(2, 10); // 1024 2의 10승을 구함 |
Math.sqrt() : 제곱근 | Math.sqrt(16) // 4 루트16은 4가 된다. |
!String methods
length : 문자열 길이 | let desc = '안녕하세요.'; desc.length // 6 |
특정 위치에 접근 | let desc = '안녕하세요.'; desc[2] // '하' desc[4] = '용'; console.log(desc); // 안녕하세요. 배열과 다르게 바꿀수 없음 |
toUpperCase() , toLowerCase() : 대문자, 소문자로 바꿈 | let desc = "Hi guys."; desc.toUpperCase(); // "HI GUYS" desc.toLowerCase(); // "hi guys" |
str.indexOf(text) | let desc = "Hi guys. Nice to meet you."; desc.indexOf('to'); // 14 desc.indexOf('man'); // -1 찾는 문장이 없을시 -1반환 if(desc.indexOf('Hi') > -1 { console.log('Hi가 포한된 문장입니다.'); } Hi는 인덱스 0이기 때문에 false 나옴 그래서 -1를 넣어줌 |
str.slice(n, m) : 시작점 과 양수면 그 숫자 음수면 끝에서부터 | let desc = "abcdefg"; desc.slice(2) // "cdefg" desc.slice(0, 5) // "abcde" desc.slice(2, -2) // "cde" |
str.substr(n, m) : n부터 시작, m개를 가져옴 | let desc = "abcdefg"; desc.substr(2,4) // "cdef" desc.substr(-4,2) // "de" |
str.repeat(n) : n번 반복 | let hello = "hello!"; hello.repeat(3); // "hello! hello! hello!" |
!Array methods
arr.splice(n, m) : 특정 요소 지움 | let arr = [1,2,3,4,5]; arr.splice(1,2); console.log(arr); // [1,4,5] [1, |
arr.splice(n, m, x) : 특정 요소 지우고 추가 | let arr = [1,2,3,4,5]; arr.splice(1, 3, 100, 200); console.log(arr); // [1, 100, 200, 5] [1, let arr = [1,2,3,4,5]; arr.splice(1, 0, 100, 200); // [1, 100, 200, 2, 3, 4, 5] 인덱스 1앞에 추가됨 |
arr.splice() : 삭제된 요소 반환 | ler arr = [1,2,3,4,5]; let result = arr.splice(1,2); console.log(arr); // [1,4,5] console.log(result); // [2,3] |
arr.slice(n, m) : n부터 m까지 반환 | let arr = [1,2,3,4,5]; arr.slice(1, 4); // [2,3,4] |
arr.concat(arr2, arr3 ..) : 합쳐서 새배열 반환 | let arr = [1,2]; arr.concat([3,4]); // [1,2,3,4] arr.concat([3,4], [5,6]); // [1,2,3,4,5,6] arr.concat([3,4],5,6); // [1,2,3,4,5,6] 5랑6을 각각 전달해도 반환은 동일함 |
arr.forEach(fn) : 배열 반복 | let users = ['Mike', 'Tom', 'Jane']; users.forEach((item, index, arr) => { }); item: Mike, Tom, Jane / index: 0,1,2 를 가르킴 |
arr.indexOf / arr.lastIndexOf : 인덱스 번호 반환 | let arr = [1,2,3,4,5,1,2,3]; arr.indexOf(3); // 2 arr.indexOf(3,3) // 7 arr.lastIndexOf(3); // 7 |
arr.includes() : 포함하는지 확인 | let arr = [1,2,3]; arr.includes(2); // true 배열내 포함 arr.includes(7); // false 배열내 미포함 |
arr.find(fn) / arr.findIndex(fn) : 첫번째 true 값만 반환하고 끝 만약 없으면 undefined를 반환 | let arr = [1,2,3,4,5]; const result = arr.find((item) => { return item % 2 === 0; }); console.log(result); // 2 값 하나만 반환 하고 끝 let userlist = [ {name: "Mike", age: 30}, {name: "Jane", age: 27}, {name: "Tom", age: 10}, ]; const result = userlist.find((user) => { if(user.age < 19) { return true; }return false; } console.log(result); // {name: "Tom", age: 10} findIndex 작성시 조건에 맞는 인덱스 번호 반환 |
arr.filter(fn) : 만족하는 모든 요소를 배열로 반환 | let arr = [1,2,3,4,5]; const result = arr.filter((item) => { return item % 2 === 0; }); console.log(result); // [2,4] find랑 다르게 조건에 맞는 모든요소들을 반환 배열로! |
arr.reverse() : 역순으로 재정렬 | let arr = [1,2,3,4,5] arr.reverse() // [5,4,3,2,1] |
arr.map(fn) : 함수를 받아 특정 기능을 시행하고 새로운 배열을 반환 | let userlist = [ {name: "Mike", age: 30}, {name: "Jane", age: 27}, {name: "Tom", age: 10}, ]; const newUserList = userlist.map((user, index) => { return Object.assign({}, user, { id: index + 1, isAdult: user.age > 19, }); }); console.log(newUserList); // {name: "Mike", age: 30, id: 1, isAdult: true}, ... console.lof(userlist); // {name: "Mike", age: 30}, 본래 객체는 건드리지 않음 ... |
Array.isArray() : 배열요소인지 찾는 매소드 | let user = {name: "Mike", age: 30,} let userList = ["Mike", "Tom", "Jane"] console.log(typeof user, typeof userList) // object console.log(Array.isArray(user), Array.isArray(userList)) // user: false, userList: true |
!arr.sort() / arr.reduce()
arr.sort() : 배열 재정렬 !배열 자체가 변경되니 주의 | let arr = [27, 8, 5, 13] arr.sort() console.log(arr); // [13,27,5,8] 앞자리 숫자로 인식해 정렬함 let arr = [27,8,5,13] arr.sort((a,b) => { return a -b; }) console.log(arr); // [5,8,13,27] a가 크면 양수를 리턴 같으면 0 a가 작으면 음수를 리턴 즉 a가 작으면 앞으로 a가 크면 그대로 |
https://lodash.com/ :정렬해주는 라이브러리 | _.sortBy(arr) 숫자든 객체든 문자든 원하는 기준으로 정렬 |
arr.reduce() : 배열을 돌면서 원하는 값을 반환 | (누적 계산값, 현재값) => { return 계산값 } let arr = [1,2,3,4,5] const result = arr.reduce((prev, cur) => { return prev + cur; }, 0) console.log(result) // 15 현재 초기값 0이 prev에 들어감 순회하면서 현재값을 더함 |
let userList = [ {name: "Mike", age:30}, {name: "Tom", age:10}, {name: "Jane", age:27}, {name: "Sue", age:26}, {name: "Harry", age:45}, ] |
//모든 나이 합산 함수 let result = userList.reduce((prev, cur) => { return (prev + cur.age); }, 0) console.log(result) // 196 //이름이 세자리인사람 함수 let result = userList.reduce((prev, cur) => { if(cur.name.length === 3) { prev.push(cur.name); } return prev; }, []) console.log(result) // ["Tom", "Sue"] |
구조 분해 할당 (Destructuring assignment)
Destructuring assignmaent | 구조 분해 할당 구문은 배열이나 객체의 속성을 분해해서 그 값을 변수에 담을 수 있게 하는 표현식 |
배열 구조 분해 | let [x, y] = [1, 2] console.log(x) // 1 console.log(y) // 2 x는 1이 들어감 y는 2가 들어감 |
let users = ["Mike", "Tom", "Jane"] | let [user1, user2, user3] = users console.log(user1) // "Mike" console.log(user2) // "Tom" console.log(user3) // "Jane" let user1 = users[0] let user2 = users[1] let user3 = users[2] 할당이 이런식으로 들어감 |
let srt = "Mike/Tom/Jane" | let [user1,user2,user3] = str.split('/') console.log(user1) // "Mike" console.log(user2) // "Tom" console.log(user3) // "Jane" split 사용(배열로 나눠짐) 기준점 요소로 원소가 나눠짐 |
배열 구조 분해 : 기본값 | let [a,b,c] = [1,2] c는 undefind let [a=3, b=4, c=5] = [1,2] console.log(a) // 1 console.log(b) // 2 console.log(c) // 5 1,2는 잘들어오고 c는 기본갓으로 할당 |
배열 구조 분해 : 일부 반환값 무시 | let [user1, ,user2] = ["Mike", "Tom", "Jane", "Tony"] user1 = "Mike" user2 = "Jane" "Tom은 공백으로 건너뛰고 "Tony"는 무시 |
배열 구조 분해 : 바꿔치기 | 새로운 변수 선언하고 할당 필요 없이 [a,b] = [b,a] 사용하면 a랑 b가 서로 바뀐다 |
객체 구조 분해 | let user = {name: "Mike", age:30} let {name, age} = user name // "Mike" age // 30 각 name,age 변수에 user.name 과 user.age를 봄 |
객체 구조 분해 : 새로운 변수 이름으로 할당 | let {name:userName, age:userAge} = user userName // "Mike" userAge // 30 키의 이름을 바꿀 수 있음 |
객체 구조 분해 : 기본값 | let user = {name: "Mike", age:30} let {name, age, gender} = user gender undefined가 나옴 let {name, age, gender = "male"} = user 기본값을 할당한다 만약 user 객체에 gender가 있을시 그 값을 사용 |
!나머지 매개변수, 전개구문 (Rest parameters, Spread syntax)
인수전달 | function showName(name) {} (name) 개수 제한 없음 |
arfuments | >함수로 넘어 온 모든 인수에 접근 >함수내에서 이용 가능한 지역 변수 >length / index >Array 형태의 객체 >배열의 내장 메서드 없음 (forEach, map) funcrion showName(name) { console.log(arguments.length); console.log(arguments.[0]); console.log(arguments.[1]); } showName("mike", "Tom") // >2 >"Mike" >"Tom" |
나머지 매개변수(Rest parameters) | function showName(...names) { console.log(names); } showName() // [] showName("Mike") // ["Mike"] showName("Mike", "Tom") // ["Mike", "Tom"] names 배열안에 인수들이 들어감 |
function add(...numbers) { let result = 0; numbers.forEach((num) => (result += num)); console.log(result); } |
add(1,2,3) // 6 add(1,2,3,4,5,6,7,8,9,10) // 55 ...numbers 는 배열이랑 length가 있기 때문에 for문 사용가능 forEach문 배열메서드 사용가능 |
function add(...numbers) { let result = numbers.reduce((prev, cur) => prev + cur); console.log(result); } |
add(1,2,3) // 6 add(1,2,3,4,5,6,7,8,9,10) // 55 reduce() 도 사용가능 |
user 객체를 만들어 주는 생성자 함수 function User (name, age, ...skills) { this.name = name; this.age = age; this.skills = skills; } const user1 = new User("Mike", 30, "html", "css") const user2 = new User("Tom", 25, "JS", "React") const user3 = new User("Jane", 10, "English") |
console.log(user1) // {name:"Mike", age:30, skills: Array(2)} console.log(user2) // {name:"Tom", age:25, skills: Array(2)} console.log(user3) // {name:"Jane", age:10, skills: Array(1)} 나머지 매개변수는 배열로 들어옴 |
전개 구문(Spread syntax) : 배열 / 객체 | let arr1 = [1,2,3] let arr2 = [4,5,6] let result = [0,...arr1,...arr2,7,8,9] // {0 ~ 9] 중간에 넣어도 됨 let user = {name:"Mike"} let mike = {...user, age:30} mike // {name:"Mike", age:30} 객체도 가능 |
전개 구문(Spread syntax) : 복제 | let user = {name:"Mike", age:30} let user2 = {...user} user2.name = "Tom" console.log(user.name) // "Mike" console.log(user2.name) // "Tom" 객체복제 assign처럼 작동 |
arr1 을 [4,5,6,1,2,3] 으로 let arr1 = [1,2,3] let arr2 = [4,5,6] let result = [...arr2, ...arr1] |
console.log(result) // [4,5,6,1,2,3] |
user 객체의 모든 원소 병합 let user = {name:"Mike"} let info = (age:30} let fe = ["JS", "React"] let lang = ["korean", "English"] |
user = Object.assign({}, user, info, { skills: []}); fe.forEach((item) => { user.skills.push(item);}); lang.forEach((item) => { user.skills.push(item);}); console.log(user) // {name: 'Mike', age: 30, skills: [ 'JS', 'React', 'Korean', 'English' ]} 코드가 복잡함 user = { ...user, ...info, skills: [ ...fe, ...lang, ], }; console.log(user); // {name: 'Mike', age: 30, skills: [ 'JS', 'React', 'Korean', 'English' ]} 코드가 단순함 |
클로저 (Closure)
어휘적 환경(Lexical Environment) let one; one = 1; function addOne(num) { console.log( one + num); } addOne(5) |
전역 Lexical 환경 : one : 1 / addOne : function 내부 Lexical 환경: num : 5 함수 내부를 먼저 참조후 없을 시 외부를 참조함 |
어휘적 환경(Lexical Environment) 다른 문제 function makeAdder(x) { return function(y) { ! return x + y; } } const add3 = makeAdder(3) ! console.log(add3(2)) |
전역 Lexical 환경 : makeAdder : function / add3 : 초기화X makeAdder Lexical 환경 : x : 3 익명함수 Lexical 환경 : y : 2 ! y 를 가지고 있고 상위함수인 makeAdder 의 x 에 접근 가능 ! add3 함수가 생성된 이후에도 상위함수인 makeAdder 의 x 에 접근 가능 |
클로저(Closure)란? | >함수와 렉시컬 환경의 조합 >함수가 생성될 당시의 외부 변수를 기억 >생성 이후에도 계속 접근 가능 |
setTimeout / setInterval
setTimeout : setInterval : |
일정 시간이 지난 후 함수를 실행 일정 시간 간격으로 함수를 반복 |
function showName(name) { console.log(name); } setTimeout(showName, 3000, "Mike") |
"Mike"인수는 함수 첫번째 인수로 전달 |
clearTimeout(tId) | 예정된 타임아웃을 없앤다 const tId = function showName(name) { console.log(name); } setTimeout(showName, 3000, "Mike") clearTimeout(tId) 상수를 선언하면 스케줄링을 취소 함 |
function showName(name) { console.log(name); } const tId = setInterval(showName, 3000, "Mike") |
3초마다 함수가 실행한다 // "Mike" "Mike" "Mike" 중간에 중단하려면 clearInterval(tId) 를 선언 |
!call, apply, bind
call | call 메서드는 모든 함수에서 사용할 수 있으며, this를 특정값으로 지정할 수 있습니다. |
const mike = { name: "Mike", } const tom = { name: "Tom", } function update(birthyear, occupation) { this.birthYear = birthyear; this.occupation = occupation; } update.call(mike, 1999, "teacher") console.log(mike) // {name: "Mike", birthYear: 1999, occupation: "teacher"} |
this로 사용할 mike 전달 두번째 매개변수 부터는 함수가 사용할 매개변수를 참조 |
apply | apply는 함수 매개변수를 처리하는 제외하면 call과 완전히 같습니다. call은 일반적인 함수와 마찬가지로 매개변수를 직접 받지만, apply는 매개변수를 배열로 받습니다. |
const nums = [3, 10, 8, 5, 1]; const minNum = Math.min.apply(null, nums); // = Math.min.apply(null, [3, 10, 8, 5, 1]) const maxNum = Math.max.call(null, ...nums); // = Math.max.apply(null, 3, 10, 8, 5, 1) console.log(minNum) console.log(maxNum) |
call은 직접받고, apply 는 매개변수를 배열로 받는다 |
bind | 함수의 this 값을 영구히 바꿀 수 있습니다. |
const user = { name: "Mike", showName: function() { console.log(`hello, ${this.name}`); }, }; user.showName(); let fn = user.showName; fn.call(user); fn.apply(user); const bindFn = fn.bind(user); bindFn(); // 'hello, Mike' |
점 앞이 this를 가르키는데 fn만 호출시 this가 없어 name이 안나옴 그래서 call, apply, bind 를 사용하여 명시해준다. |
!상속,프로토타입(Prototype)
hasOwnProperty() | 해당 내장객체 프로퍼티만 있으면 트루 그외 flase |
const car = { wheels: 4, drive() { console.log("drive..."); }, }; const bmw = { color: "red", navigation: 1, }; bmw.__proto__ = car; for(p in bmw) { console.log(p); } // color, navigation, wheels, drive |
bmw.color // red bmw.wheels // 4 bmw 객체의 color 있으니 탐색후, 멈춘다. bmw 객체의 wheels 없으니 __proto__ 까지 탐색후, 멈춘다. |
x5객체를 만들고 bmw을 상속을 한다. const x5 = { color: "white", name: "x5", }; x5.__proto__ = bmw; |
x5.color // white x5.navigation // 1 x5 객체의 color가 white 있으니 탐색후, 멈춘다. x5 객체의 navigation 없으니 bmw__proto__ 까지 탐색후 있으니 탐색후, 멈춘다. Prototype Chain |
Object.keys/values | 해당 객체의 내장 객체인 키 값만 호출 할 수있다. |
생성자 함수 사용 const car = { wheels: 4, drive() { console.log("drive..."); }, }; const Bmw = function (color) { this.dolor = color; }; const x4 = new Bmw("red"); const z4 = new Bmw("blue"); x4.__proto__ = car; z4.__proto__ = car; |
생성자 함수가 생성하는 객체의 proto을 prototype의 직접 설정합니다. 하나씩 객체의 proto를 넣어줄 필요 없다. const Bmw = function (color) { this.dolor = color; }; Bmw.prototype.wheels = 4; Bmw.prototype.drive = function () { console.log("drive.."); }; const x4 = new Bmw("red"); const z4 = new Bmw("blue"); |
z4 instanceof Bmw // true | 해당 객체가 생성자 함수로 부터 생성 됐는지 확인 |
z4.constructor === Bmw // true | 해당 생성자 함수가 맞는지 true,false 반환 |
const Bmw = function (color) { this.dolor = color; }; Bmw.prototype = { constructor: Bmw, wheels: 4, drive() { console.log("drive.."); }, }; const x4 = new Bmw("red"); const z4 = new Bmw("blue"); console.log(z4.constructor === Bmw) |
프로토타입을 덮어서 작성시 constructoe가 flase가 나온다. 그래서 수동으로 constructor을 명시할 수 있다. |
!클래스(Class)
생성자 함수의 new를 없앰 const User = function (name, age) { this.name = name; this.age = age; this.showName = function () { console.log(this.name); }; }; const tom = User("Tom", 20); // undefined |
생성자함수의 new를 없애고 실행시키면 return 값이 없기 때문에 undefined가 뜬다 (생성자함수는 error가 안뜨고 정상적으로 나온다.) |
class 함수의 new를 없앰 class User2 { constructor(name, age) { this.name = name; this.age = age; }; showName() { console.log(this.name); }; }; const mike = User2("Mike", 30); // typeerror "new" |
클래스는 new 없이는 error가 뜬다. 클래스로 생성된 constructor는 class 를 가지고 있기 때문에 new없이 실행시 에러가 발생하도록 설계함 |
Class : 상속은 extends를 사용함 class Car { constructor(color) { this.color = color; this.wheels = 4; } drive() { console.log("drive.."); } stop() { console.log("STOP"); } } class Bmw extends Car { park() { console.log("PARK"); } } const z4 = new Bmw("blue"); |
클래스로 선언한 메소드는 프로토타입 밑으로 들어간다. z4.drive()를 치면 z4객체안에서 찾는다. 없으면 상속한 Car프로토타입까지 탐색후, 멈춘다. |
Class : 메소드 오버라이딩(method Overriding) class Bmw extends Car { park() { console.log("PARK"); } stop() { super.stop(); console.log("OFF"); } } |
상속을 받아온 Bmw 클래스에 stop()메소드를 중복시 덮어씌우게 된다. OFF가 나온다. 이와 같이 super.stop()을 선언하여 Car의 메소드도 같이 나온다. |
Class : 오버라이딩(overriding) class Bmw extends Car { constructor() { this.navigation = 1; } park() { console.log("PARK"); } } 인수를 넣어주고 super을 넣어줌 constructor(color) { super(color); this.navigation = 1; } |
constructor에서 this를 사용하기 전에, super 을 명시해야 부모 생성자를 반드시 먼저 호출해야 한다. constructor는 빈객체를 만들고 this는 빈객체를 가르킴 하지만, 자식 클래스는 건너뜀 자식 constructor에도 부모와 동일한 인수 작업을 넣어줘야함 |
!Promise
const pr = new Promise((resolve, reject) => { //code }); |
함수로 전달 받음 인수는 resolve, reject 이다. resolve는 성공할 때 실행되고, reject는 실패할 때 실행됨 어떤 일을 완료하고 실행되는 함수를 콜백(callback)함수다 |
new Promise state : pending(대기) 초기는 대기상태 result : undefinded //resolve(value) 호출 true state : fulfilled(이행됨) result : value //reject(error) 호출 flase state : rejected(거부됨) result : error |
new 생성한 프로미스는 객체를 갖는다. state와 result를 갖는다. resolve(성공) 하면 fulfilled가 호출됨 이때 result는 resolve함수로 전달 된 값 rejected(실패) 하면 rejected가 호출됨 이때 result는 reject 함수로 전달 된 값 |
const pr = new Promise((resolve, reject) => { setTimeout(()=>{ resolve("OK"); },3000) }); const pr = new Promise((resolve, reject) => { setTimeout(()=>{ reject(new Error("error..")); },3000) }); |
3초뒤 실행 result는 OK로 반환 state:pending(대기) => stata:fulfilled(이행됨) result:undefined => result:'OK' 3초뒤 실행 result는 error반환 state:pending(대기) => stata:rejected(거부됨) result:undefined => result:error |
pr.then( function(resilt){}, function(err){} ); |
pr.then( function(result){} ).catch( function(err){} ) // 이와 같이 catch문을 바꿀수 있음 동작은 똑같음 |
pr.then( F() ).catch( F() ).finally( function(){ console.log('---주문 끝---') } ) |
finally는 이행이든 거부든 처리가 완료되면 실행 |
console.log("시작"); f1() .then((res) => f2(res)) .then((res) => f3(res)) .then((res) => console.log(res)) .catch(console.log) .finally(() => { console.log("끝"); }); |
// 시작 -> 1번주문완료 -> 2번주문완료 -> 3번주문완료 -> 끝 연결 되는 프로미스를 프로미스 체이닝(Promise chaining) 이라고 한다. !가져온 데이터 순으로 화면을 그릴수 있다. |
상품을 한번에 다 받아오는 메서드 : Promise.all Promise.all([f1(), f2(), f3()]).then((res) => { console.log(res); }); |
// ["1번주문완료, "2번주문완료", "3번주문완료"] 각 프로미스로 넘겨준 값이 배열로 넘어옴 setTimeout이 3초가 최대라 3초 안에 다받아옴 모두 이행 되어야 값을 사용할수 있다. reject 사용시 new Error() 어떠한 데이터도 못 얻는다. !하나라도 정보가 누락될 경우 페이지를 보여주면 안될때 사용한다. |
하나라도 먼저 반환되면 끝내는 메서드 : Promise.race Promise.race([f1(), f2(), f3()]).then((res) => { console.log(res); }); |
1번 주문 완료 // 1번 res나오고 이미 1번이 나와서 2번 rej은 무시한다. |
'JAVASCRIPT' 카테고리의 다른 글
자바스크립트 함수 및 기술들 복습자료 (1) | 2024.02.05 |
---|