function add(a, b = 10){
console.log(a + b)
}
add(1); //11
이런식으로 작성했을 때, 파라미터를 하나만 줬을 경우, 디폴트로 설정해준 파라미터인 10이 b에 할당되어 콘솔창에 11이 출력된다.
function add(a, b = 2 * 5){
console.log(a + b)
}
add(1); //11
이런식으로 연산자도 가능하다.
function add(a, b = 2 * a){
console.log(a + b)
}
add(3); //9
이런식으로 다른 파라미터와 연산도 가능하다.
function f(){
return 10
}
function add(a, b = f() ){
console.log(a + b)
}
add(3);//13
이런 방식으로 디폴트 파라미터 자리에 함수를 할당할 수도 있다.
함수의 모든 파라미터들을 한꺼번에 다룰 때 사용한다.
function f(a,b,c){
console.log(arguments)
}
f(2,3,4);//[2,3,4]
콘솔창에 [2,3,4]가 출력된다.
function f(a,b,c){
for (var i = 0; i < arguments.length; i++){
console.log(arguments[i])
}
}
f(2,3,4);
//2
//3
//4 와 같이 출력된다.
위와 같이 작성했을 경우, arguments들을 따로 쓸 수 있다.
ES6에서 제공하는, argument를 대체해서 자주 쓰인다.
function f(...par){
console.log(par)
}
f(1,2,3,4,5,6,7);//[1,2,3,4,5,6,7]
이와 같이 작성할 경우 [1,2,3,4,5,6,7] 이런 배열을 출력해준다.
function f(a,b, ...par){
console.log(par)
}
f(1,2,3,4,5,6,7);//[3,4,5,6,7]
이런 코드를 실행하주면 [3,4,5,6,7]의 배열이 출력된다. a,b 뒤로 나오는 모든 파라미터들을 array
로 만들어준다.
🤔주의점: 나머지 부분에만 사용해야 함.
function 함수2(a, ...par, b){ console.log(par) }
이런식으로 가운데 쓰거나
function 함수2(a, ...par, ...par2){ console.log(par) }
이런식으로 2개 이상 쓸 수 없다.
function f(...par) {
for(let i=0; i<par.length;i++){
console.log(par[i]);
}
}
f(1, 2, 3, 4, 5);
var a = [1,2,3];
var b = '김밥';
var c = [...b, ...a];
console.log(c);//['김','밥',1,2,3]
출력 결과는 ['김','밥',1,2,3] 이 된다.
var a = [1,2,3];
var b = ['you', 'are'];
var c = function(a,b){
console.log( [[...a], ...[...b]][1] )//[[1,2,3],'you','are'][1]
}
c(a,b);
[[...a], ...[...b]][1] 은 [[1,2,3],'you','are'][1]이 되므로 따라서 콘솔창에는 you가 출력된다.
function f(a = 5, b = a * 2 ){
console.log(a + b);//15
}
f(undefined, undefined);
위와 같은 방식으로 작성했을 경우, f(undefined, undefined)는 f()나 마찬가지이므로 출력결과는 15가 된다.
function arr(){
//여기 어떤코드가 들어가면 될까?
}
var newArray = arr(1,2,3,4,5);
console.log(newArray);
이런 코드가 주어졌을 때, [1,2,3,4,5]가 출력되도록 해보자
function arr(...rest){
return rest
}
var newArray = arr(1,2,3,4,5);
console.log(newArray);
이런 식으로 rest를 리턴해서 나타낼 수 있다.
Math.max(5,6,4,3)
이런 코드를 작성해서 최댓값을 구할 수 있는데
var numbers = [2,3,4,5,6,1,3,2,5,5,4,6,7];
이 numbers를 Math.max()에 집어넣어서 사용해보자.
var numbers = [2,3,4,5,6,1,3,2,5,5,4,6,7];
console.log( Math.max(...numbers) );
이런 식으로 spread를 사용해서 표현할 수 있다.
🤔 주의점: 함수를 선언할 땐 ...은 rest 파라미터
함수를 사용할 땐 ...은 spread 연산자다.
console.log( ['b', 'c', 'a'].sort() );//['a', 'b', 'c']
이렇게 작성하면 ['a', 'b', 'c']가 출력된다.
function sorting(){
//여기 어떤 코드가 들어가야할까
}
sorting('bear');
bear라는 문자를 알파벳순으로 aber로 정렬하는 코드를 작성해보자
function sorting(a){
console.log( ...[...a].sort() )//a b e r
}
sorting('bear');
[...a]를 사용하면 ['b','e','a','r'] 이렇게 되고, sort()로 정렬하면 ['a','b','e','r']이 된다. 또 이 정렬한 데이터를 대괄호를 빼고 나타내고 싶다면 다시 ...을 써서 표현하면 된다. → ...[...a].sort()
이때, a b e r 로 출력된다.
알파벳의 출현 갯수를 세는 함수를 만들어 보자
만약, count('aaacbb')를 입력하면 {a:3,b:2:c:1}를 출력해주도록 작성할 것이다.
function count(letter){
var res = {};
[...letter].forEach(function(a){
if( res[a] > 0 ){ res[a]++ } else { res[a] = 1 }
});
console.log(res)
}
먼저 [...letter]를 사용해 'aaacbb'라는 문자열을 ['a','a','a','c','b','b']로 변환한 뒤에 forEach를 사용해 하나씩 반복문을 돌려 0일 경우 1로 만들어주고, 1이상일 경우는 1을 더해주도록 작성했다.
자바스크립트의 자료형은 primitive
, reference
로 크게 2가지로 분류할 수 있다.
primitive datatype
은 자료자체가 변수에 저장된다. ex.문자, 숫자 자료형
array, object 자료형이 여기 속한다.
자료를 직접 변수에 저장하지 않고, 레퍼런스를 변수에 저장한다.
var person = { name : 'youngki' };
이렇게 작성했을 때, 변수에 저장된건 { name : 'youngki' }를 가르키는 레퍼런스가 저장된 것이다.
var name1 = 'young';
var name2 = name1;
name1 = 'ki';
이런식으로 primitive 자료형을 복사하면, name2는 young, name1은 ki가 된다.
reference 타입인 object를 사용해 복사해보자
var name1 = { name : 'young' };
var name2 = name1;
name1.name = 'ki';
이런식으로 작성한다면 name1과 name2는 어떤 값이 될까? 값이 아닌 레퍼런스를 가르키고 있으므로 name1이 변경되면 name2도 변경되므로 둘다 {name:'ki'}를 가르키게 된다.
var name1 = { name : 'youngki' };
var name2 = { name : 'youngki' };
위와 같은 방식으로 작성했을 때, name1==name2를 한다면 true가 나올까 false가 나올까? 답은 false이다.
값은 같지만 레퍼런스는 각각 생성되기 때문이다.
var name1 = { name : 'young' };
function change(obj){
obj = { name : 'ki' };
}
change(name1);
해당코드를 실행하면 name1을 변경할 수 있을까? 답은 '아니오'이다.
위의 코드에서 name1을 넣고는 있지만 실제로 change(var obj = name1) 이런식으로 들어가고 있기 때문에 obj에 name1이 가르키는 레퍼런스를 가르키게 한 후에 함수 안에서 다시 { name : 'ki' } 이런 레퍼런스를 가르키고 있기 때문에 변하는 건 파라미터로 쓰이는 obj이고 name1은 변하지 않는다.
object를 안전하게 복사하기 위해 쓰이는 문법
var s1 = { name : 'Kim', age : 15 };
var s2 = { name : 'Park', age : 15 };
...
이런 식으로 학생 리스트를 많이 만들어야 할때, 더 편하게 만들기 위해 아래의 방법을 사용한다.
//var s1 = { name : 'Kim', age : 15 };
function f(){
this.name = 'Kim';
this.age = 15;
}
var s1 = new f();
var s2 = new f();
또한, 함수가 들어가야 할때도, 위와 같은 방법으로 작성할 수 있다.
var s1 = {
name : 'Kim',
age : 15
sayHi : function(){
console.log('안녕하세요' + this.name + ' 입니다');
}
};
s1.sayHi();
이 코드를 다시 작성해보자.
function f(){
this.name = 'Kim';
this.age = 15;
this.sayHi = function(){
console.log('안녕하세요' + this.name + ' 입니다');
}
}
var s1 = new f();
var s2 = new f();
s2.sayHi();
위와 같은 방식으로 작성할 수 있다.
속성을 다르게 주기 위해 파라미터를 부여해 아래와 같은 방식을 사용한다.
function f(name){
this.name = name;
this.age = 15;
this.sayHi = function(){
console.log('안녕하세요' + this.name + ' 입니다');
}
}
var s1 = new f('Park');
var s2 = new f('Kim');
앞에서 작성했던 f 함수안에는 prototype
이 내부에 생성되어 있다.
function f(){
this.name = 'Kim';
this.age = 15;
}
var s1 = new f();
var s2 = new f();
console.log(f.prototype);
이 prototype은 부모의 유전자역할을 해준다.
function f(){
this.name = 'Kim';
this.age = 15;
}
f.prototype.gender = '남';
var s1 = new f();
var s2 = new f();
console.log(s1.gender); //'남'이 출력
이런식으로 prototype을 지정한 후에(부모에다) 변수를 추가한 후에 값을 추가할 수있다. 따라서 위의 코드에서 s1, s2에는 gender가 추가되어있고, '남'이라는 값이 들어가 있다.
자바스크립트에서는 오브젝트에서 값을 출력할 때, 해당 순서로 값을 찾는다.
s1.gender라는 코드를 보고 먼저 s1에서 gender를 찾고, 없다면 부모에서 gender를 찾고, 없다면 부모의 부모에서 gender를 찾고 ... 이런 방식으로 동작한다.
var arr = [1,2,3];
console.log( arr.toString() ); //가능
이런식으로 toString이라는 내장함수를 쓸 수 있는 이유는 arr가 toString 메서드를 갖고 있지 않아도 부모, 혹은 부모의 부모에 toString()을 갖고 있기 때문이다. 여기서는,
var arr = [1,2,3];
var arr = new Array(1,2,3);
이 코드가 같은 의미 이므로 Array에서 sort, map, push 이런 함수를 갖고 있기 때문에 arr도 똑같이 쓸 수 있는 것이다.
일반 object, array를 만들 때, prototype은 없음
부모로 부터 생성된 자식 object들은 __proto__라는 속성이 있다. 따라서 __proto__는 부모의 prototype과 같은 의미이다.
function f(){
this.name = 'Kim';
this.age = 15;
}
var s1 = new f();
console.log(s1.__proto__);
console.log(f.prototype);
콘솔에는 각각 같은 결과가 나온다.
var parent = { name : 'Kim' };
var child = {};
child.__proto__ = parent;
console.log(child.name);
위와 같이 작성했을 경우 child의 부모 유전자는 { name : 'Kim' }이라는 parent 오브젝트가 되고 child는 child.name 속성을 사용할 수 있다.
function f() {
this.name = 'Kim';
this.age = 15;
}
f.prototype.gender = '남';
var s1 = new f();
console.log(s1);
이렇게 콘솔창에 찍어보면
이런식으로 prototype으로 Object가 떠있는 것을 확인할 수 있다.
prototype을 열어보면 밑과 같이 부모의 부모도 확인할 수 있다.
해당 방식으로 부모의 부모를 탐색할 수 있으며, 모든 object 자료형의 조상은 Object()임을 알수 있고, array 자료형, 함수 자료형의 조상도 Object()임을 알 수 있다.
function Parent(){
this.name = 'Young';
}
var a = new Parent();
a.__proto__.name = 'Ki';
console.log(a.name)
이렇게 작성했을 경우 출력결과는 어떻게 될까? 답은 'Young'이다. a.name은 'Young'이고, a의 부모의 name에 'Ki'를 추가해주었으나, a.name을 구하고 있으므로 직접 갖고 있는 name인 'Young'을 먼저 출력해준다. 직접갖고 있지 않은 경우엔 부모로 올라가 'Ki'를 출력해주었을 것이다.
function Student(name, age){
this.name = name;
this.age = age;
}
Student.prototype.sayHi = () => {
console.log('안녕 나는 ' + this.name + '이야');
}
var s1 = new Student('Kim', 20);
s1.sayHi(); //왜 이 코드가 제대로 동작하지 않을까?
위의 코드는 의도한 대로 동작하지 않는다. 왜일까?
arraw function을 썼기 때문에 this가 바깥의 this를 쓰기 때문이다. 여기서 this를 출력해보면 window가 나온다. 따라서 뜻대로 동작하지 않았다.
var arr = [1,2,3];
arr.remove3();
console.log(arr); //[1,2]
이런 코드가 있을 때, 자체적으로 만든 remove3() 메서드를 사용하면 배열에서 3을 제거하도록 하고 싶다. remove3()을 어떻게 작성해야 할까?
먼저, 모든 array에 적용할 수 있게 하기 위해서 prototype을 떠올릴 수 있다. 부모에 해당 함수를 추가한다면 자식인 array에서 전부 동작할 것이다. 그렇다면 다음과 같이 작성할 수 있다.
Array.prototype.remove3 = function(){ for (var i = 0; i < this.length; i++) { if ( this[i] === 3 ) { this.splice(i,1); } } };
이와 같이 작성하면 의도한 대로 동작한다.