function을 선언하는 것은 세가지 방법이 있다.
- function declaration : 호이스팅이 적용된다.
- function expression : 호이스팅이 적용되지 않는다.
first();
// function declaration : 호이스팅
function first() {
console.log('first');
}
// function expression : 호이스팅 적용 x
const second = function() {
console.log('second');
}
second();
console.log(typeof second);
// Arrow function : 함수의 이름을 없애고 함수의 실행문을 줄여서 사용하는 것
const third = () => {
console.log('third');
}
같은 함수를 다른 변수에 선언하고 프로퍼티를 수정하면 모두 영향을 받는다.
third.userName = 'Lee';
console.log("third name :", third.userName); // Lee
const forth = third;
console.log(forth.userName); // Lee
forth.userName = 'Park';
console.log(forth.userName); // Park
console.log("third name : ", third.userName); // Park
컴퓨터 랭귀지에서 펑션을 다룰때 마치 데이터처럼 메모리에 저장된 펑션을 이리저리 주고받을 수 있는 것을 말한다. *Higher Order Function을 위하여.
// 아규먼트로 던질 펑션
var sum = function(x, y) {
return x + y;
};
// 펑션을 아규먼트로 받을 펑션
var run = function(fn, a, b) {
console.log(fn(a, b));
};
run(sum, 10, 5); // 15
run(funtion(){ return x * y}, 10, 5); // 50
펑션은 네가지 실행방법이 존재한다.
- 펑션
- 메소드
- 컨스트럭터 (new)
- call(), apply()
var invokeFunc = function(value) {
console.log(this);
console.log(value);
console.log(arguments);
console.log(arguments[1]);
};
this는 window 오브젝트를 반환한다.
invokeFunc(3,4,5,6);
복수의 아규먼트를 처리할때 arguments를 사용할 수 있다.
var sumIt = function() {
var sum = 0;
for(let i = 0; i < arguments.length; i++;) {
sum += argments[i];
}
};
오브젝트는 두가지 방식으로 선언할수 있다.
- Object Literal
- Object Constructor
// object literal
var obj = {
fName: "Steven",
lName: "Hancook",
greet: function(){
console.log(this);
}
};
// object constructor
var obj2 = new Object();
obj2.fNmae = "Doil";
obj2.lNmae = "Ji";
obj2.greet = function(){
console.log(this);
}
// property 삭제
delete obj.lName;
"lName" in obj; // false
obj.hasOwnProperty("lNAme"); // false
this는 펑션이 선언되는 시점과 관계 없이 실행될때 어떤 환경을 참조할지에 관한 정보를 담고 있는 오브젝트이다.
const name = global;
const funThis = function() {
const name = "local";
console.log("funthis : ", this);
console.log("this.name", this.name);
return function funThisSecond() {
const name = "localSeond";
console.log("funthisScond : ", this);
console.log("this.name", this.name);
};
};
funThis()(); // 둘다 this는 window를 반환한다.
const obj = {
name: "doil",
greet: function() {
console.log(this);
}
}
obj.greet(); // this는 obj를 리턴한다.
결론 : this는 해당 펑션을 누가 실행했느냐, 주체를 가르킨다. 따라서 .노테이션의 왼쪽을 말한다. 첫번째 사례는 window 오브젝트에 속한 펑션이며 두번재는 obj에 속한 함수이다.
- 모든 오브젝트는 prototype 오브젝트를 갖고 있다.
- 프로토타입 오브젝트는 proto프로퍼티를 갖고 있다.
- proto는 오브젝트 타입의 펑션들을 갖고 있는 상위 오브젝트를 링크해준다.
var obj = {};
"toString" in obj; // true, JS엔진이 prototype의 proto링크를 따라가 상위 오브젝트의 toString을 찾아냈다.
obj.hasOwnProperty("toString"); // false, obj는 toString 프로퍼티를 소유하고 있지 않다.
call,apply는 this를 정의해준다.
const user = {
fName: "doil",
greet: function(){
return this.fName + " good morning?";
}
};
const greet = function(term) {
console.log(term + this.fName + " how are you?");
};
greet.call(user, "hello ");
greet.apply(user, ["hi" ]);
// 이것을 응용하면 상기에서 window를 반환했던 this를 사용할 수 있다.
console.log(user.greet.call(user));
bind: 새로운 펑션을 반환해준다.
// func는 완전히 새로운 펑션이다.
var func = function.bind(this, arg1, arg2);
// data
const fName = "Doil", lName = "Ji";
const user = {
fName: "John",
lName: "Cena"
};
const fullName = function() {
console.log(this.fName + " " + this.lName);
};
fullName(); //
fullName.call(user); //
// this가 user가 아닌 global의 fName, lName을 출력한다.
const fullName = function() {
setTimeout(function(){
console.log(this.fName + " " + this.lName);
}, 2000)
};
// fix
const fullName = function() {
var that = this
setTimeout(function(){
console.log(that.fName + " " + this.lName);
}, 2000)
};
// fix 2
const fullName = function() {
setTimeout(function(){
console.log(this.fName + " " + this.lName);
}.bind(this), 2000)
};
// fix 3 arrow function은 this 문제를 해결해준다.
const fullName = function() {
setTimeout(() => {
console.log(this.fName + " " + this.lName);
}.bind(this), 2000)
};